Я совсем новичок в модульном тестировании и TDD, мои сомнения в том, что момент связан со следующим тестом, который я запускаю:
class TypeTest extends TestCase
{
private $typeNameForTests = "staff";
public function setUp()
{
parent::setUp();
}
public function testMake()
{
$type = Type::make($this->typeNameForTests);
$this->assertTrue(
$type instanceof Type,
"make() should return an instance of " . Type::class
);
return $type;
}
/**
* @depends testMake
*/
public function testToString($type)
{
$this->asserTrue(
$type->__toString() == 'staff',
"make() parameter should be set as the type name"
);
}
/**
* @depends testMake
*/
public function testSetAndGetParent($type)
{
$parent = $this->createMock(Type::class);
$type->setParent($parent);
$parent === $type->getParent();
}
}
Это нормально, как я объединяю два первых теста? Утверждение возврата метода необходимо и имеет смысл в этом случае?
Имеет ли смысл тестовая зависимость (testToString)?
А как насчет тестирования Get и Set в одном тесте?
Я ценю любой вклад, так как я чувствую, что могу слишком много думать о некоторых принципах...
Спасибо!






Чтобы ответить на ваши вопросы:
Is it ok the way I am concatenating the two first tests? Asserting the return of a method is necessary and makes sense on this case? Does the test dependency (testToString) makes sense there?
Я бы не стал вводить зависимость между этими двумя случаями, так как это фактически два разных поведения. Первый метод проверяет поведение метода make(), который создает новые экземпляры, а второй метод проверяет поведение приведения к строке.
Зависимые тесты должны быть скорее исключением, чем правилом. Используйте их, если нет другого пути, например, слишком дорого повторять вызовы в каждом методе тестирования (например, сетевые вызовы в интеграционных тестах и т. д.).
And how about testing Get and Set in the same test?
На мой взгляд, это нормально. Вы по-прежнему описываете то же поведение — после того, как родитель установлен, к нему можно получить доступ.
Мой главный совет — сосредоточиться на рассмотрении одного поведения для каждого метода тестирования, а не на рассмотрении одного метода. Обычно требуется один вызов метода, но не каждый раз.
Я бы обновил ваш тестовый пример до:
Попробуйте назвать свои методы тестирования лучше. Опишите поведение, которое вы ожидаете. Начните свои методы тестирования с testIt... или testItShould...
Вместо того, чтобы сосредоточиться на добавлении метода тестирования для каждого производственного метода, сосредоточьтесь на описании поведения (testMake против testMakeCreatesNewType). Таким образом, у вас может быть более одного метода тестирования, описывающего поведение одного производственного метода.
Избегайте @depends. Это почти никогда не нужно, и это хорошо только для интеграционных тестов, когда вам нужно сделать как можно меньше вызовов ввода-вывода. Модульные тесты должны быть независимыми.
Сосредоточьтесь на удобочитаемости каждого тестового примера. В этом конкретном примере я думаю, что частная собственность не делает вещи более читабельными.
Используйте более конкретные утверждения для лучшей обратной связи. Использование более специализированных утверждений, таких как assertInstanceOf, assertSame и т. д., дает вам лучшее сообщение об ошибке, когда тест терпит неудачу, и приводит к меньшей потребности в пользовательских сообщениях, а также эффективно делает тесты более читабельными.
Удалите бесполезный setUp(). Он вызывает только родителя, который только шумит.
class TypeTest extends TestCase
{
public function testMakeCreatesNewType()
{
$type = Type::make('staff');
$this->assertInstanceOf(Type::class, $type);
}
public function testItCanBeCastToString()
{
$type = Type::make('staff');
$this->asserSame('staff', (string) $type);
}
public function testItExposesTheParent()
{
$type = Type::make('staff');
$parent = $this->createMock(Type::class);
$type->setParent($parent);
$this->assertSame($parent, $type->getParent());
}
public function testItReturnsNullIfParentWasNotSet()
{
$type = Type::make('staff');
$this->assertNull($type->getParent());
}
}
Это сделает тесты более читабельными, удобными в сопровождении и надежными.