Проверка зависимостей и тестирование get и setter вместе - PullRequest
0 голосов
/ 07 февраля 2019

Я довольно новичок в модульном тестировании и 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 в одном тесте?

Я ценю любой вклад, так как чувствую, что могу переосмыслить некоторые принципы ...

Спасибо!

1 Ответ

0 голосов
/ 12 февраля 2019

Чтобы ответить на ваши вопросы:

Это нормально, как я объединяю два первых теста?Утверждение возврата метода необходимо и имеет смысл в этом случае?Имеет ли смысл тестовая зависимость (testToString)?

Я бы не стал вводить зависимость между этими двумя случаями, поскольку это фактически два разных поведения.Первый метод - тестирование поведения метода make(), который создает новые экземпляры, а второй - тестирование поведения приведения к строке.

Зависимые тесты должны быть скорее исключением, чем правилом.Используйте их, если нет другого способа, например, слишком дорого повторять вызовы в каждом тестовом методе (например, сетевые вызовы в интеграционных тестах и ​​т. Д.).

А как насчет тестирования Get и Set в одном тесте?

На мой взгляд, все в порядке.Вы по-прежнему описываете то же поведение - как только родитель установлен, к нему можно получить доступ.

Мой главный совет - начать фокусироваться на освещении одного поведения для каждого метода теста, а не на одном методе.Обычно требуется один вызов метода, но не каждый раз.

Я бы обновил ваш тестовый пример на:

  1. Попытайтесь назвать ваши методы тестирования лучше.Опишите поведение, которое вы ожидаете.Начните свои методы тестирования с testIt... или testItShould...

  2. Вместо того, чтобы сосредоточиться на добавлении метода тестирования для каждого производственного метода, сосредоточьтесь на описании поведения (testMake против testMakeCreatesNewType),Таким образом, вы можете иметь более одного метода тестирования, описывающего поведение одного метода производства.

  3. Избегать @depends.Вряд ли это когда-либо понадобится, и это хорошо только для интеграционных тестов, когда вам нужно сделать как можно меньше вызовов ввода / вывода.Модульные тесты должны быть независимыми.

  4. Сосредоточиться на удобочитаемости каждого теста.В этом конкретном примере, я думаю, частная собственность не делает вещи более читабельными.

  5. Используйте более конкретные утверждения для лучшей обратной связи.Использование более специализированных утверждений, таких как assertInstanceOf, assertSame и т. Д., Дает вам лучшее сообщение об ошибке, когда тест не пройден, и приводит к меньшей потребности в пользовательских сообщениях, а также делает более читабельными тесты.

  6. Удалить бесполезно 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());
    }
}

Это сделает более удобочитаемыми, поддерживаемыми и надежными тестами.

...