我对单元测试和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怎么样?
我非常感谢您的投入,因为我觉得自己可能对某些原则有误解...
谢谢!
答案 0 :(得分:1)
要回答您的问题:
我可以将两个前两个测试串联起来吗?断言方法的返回是必要的,并且在这种情况下有意义吗? 测试依赖项(testToString)在这里有意义吗?
我不会在这两种情况之间引入依赖关系,因为这实际上是两种不同的行为。第一种方法是测试创建新实例的make()
方法的行为,第二种方法是测试强制转换为字符串的行为。
从属测试应该是一个例外而不是规则。如果没有其他方法,请使用它们,例如在每种测试方法中重复调用太昂贵(请考虑在集成测试中进行网络调用等)。
如何在同一测试中测试Get和Set?
我认为很好。您仍在讨论相同的行为-设置了父级后就可以对其进行访问。
我的主要建议是开始专注于涵盖每种测试方法的单一行为,而不是涵盖单一方法。通常,将需要一个方法调用,但并非每次都需要。
我会将您的测试用例更新为:
尝试更好地命名测试方法。描述您期望的行为。从testIt...
或testItShould...
与其专注于为每种生产方法添加测试方法,不如着重描述行为(testMake
与testMakeCreatesNewType
)。这样,您可以有多个描述单个生产方法行为的测试方法。
避免使用@depends
。当您需要进行尽可能少的I / O调用时,几乎不需要它,并且仅对集成测试有用。单元测试应该是独立的。
关注每个测试用例的可读性。在这个特定示例中,我认为private属性不会使事情更具可读性。
使用更具体的断言以获得更好的反馈。使用更专业的断言,例如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());
}
}
这将使测试更具可读性,可维护性和可靠性。