我对单元测试和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怎么样?
我很感激任何意见,因为我觉得我可能会过度思考一些原则......
谢谢!
回答你的问题:
我连接两个第一次测试的方式是否正常?断言返回方法是必要的,在这种情况下有意义吗?测试依赖(testToString)是否有意义?
我不会在这两种情况之间引入依赖关系,因为它们实际上是两种截然不同的行为。第一种方法是测试创建新实例的make()
方法的行为,第二种方法是测试转换为字符串的行为。
依赖性测试应该是一个例外而不是规则。如果没有别的办法就使用它们,比如在每种测试方法中重复调用太昂贵(想想集成测试中的网络调用等)。
那么在同一个测试中测试Get和Set怎么样?
在我看来这很好。您仍然会覆盖相同的行为 - 一旦设置了父级,就可以访问它。
我的主要建议是开始专注于为每个测试方法覆盖单个行为,而不是覆盖单个方法。通常需要一个方法调用,但不是每次都需要。
我会将您的测试用例更新为:
testIt...
或testItShould...
开始您的测试方法testMake
vs testMakeCreatesNewType
)。这样,您可以使用多个测试方法来描述单个生产方法的行为。@depends
。它几乎不需要,只有当你需要进行尽可能少的I / O调用时,它才有利于集成测试。单元测试应该是独立的。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());
}
}
这将使更可读,可维护和可靠的测试成为可能。