我有以下测试(针对此问题进行了简化):
@FixMethodOrder(MethodSorters.JVM)
public class ArticleTest {
private static Article article;
@Test
public void testCreateArticle() {
articleService.create("My article");
article = articleService.findByTitle("My article");
assertNotNull(article);
}
@Test
public void testUpdateArticle() {
article.setTitle("New title");
articleService.save(article);
assertNull(articleService.findByTitle("My article"));
article = articleService.findByTitle("New title");
assertNotNull(article);
}
}
testCreateArticle
成功传递,但testUpdateArticle
在第一行失败,因为article
为null
,因此抛出了一个NPE(尽管第一个测试断言{{1} }不是article
)。
任何人都明白为什么?请注意,我使用Play Framework运行测试(喜欢字节码操作),所以这可能会以某种方式相关......
另外,我知道有依赖测试是一种不好的做法,但是IRL,这不是一个单元测试,而是一种测试场景,所以我只想尝试依赖测试自己理解为什么人们不喜欢它们;)
但无论如何,静态字段应该在测试之间共享,我错了吗?
更新:我知道我可以在null
中重新创建一篇文章,但真正的测试更复杂(可能我在创建MVCE时失败了......)。假设我有第三个测试依赖于第二个测试(取决于第一个),等等。第一个测试不需要特别的,第二个需要创建的文章,第三个需要创建然后更新的文章等。我想通过保持测试之间的状态(使它们依赖于那些)来避免每次重做所有数据库操作。
答案 0 :(得分:1)
更好的方法是使用@Before注释在每次测试之前重新创建文章对象。
@Before
public void setUp() {
articleService.create("My article");
}
这样,文章对象不需要是静态的,并且使测试更容易。
注意:不要忘记在@After
方法
@After
public void tearDown() {
articleService.delete("My article");
}
答案 1 :(得分:1)
我无法重现您的行为:
@FixMethodOrder
public class RemoveMeTest {
private static String string;
@Test
public void testOne() {
string = "foo";
}
@Test
public void testTwo() {
System.out.println("in test two: " + string) ;
}
}
输出确实是" foo"。您是否为测试用例提供了特殊配置或测试运行器?
测试用例应该真的,真的不依赖于其他测试用例。我也想提一下,即使你的案子更复杂而其他人已经提到它了;) 测试A失败,B和C也会失败,即使它们有效。您更改了测试A,运行,但B和C失败,在您的示例中更改String"我的文章",即使它们有效。如果C失败,则必须先运行A和B,以验证C是否再次运行。
最糟糕的是imo:它增加了复杂性,这是完全没必要的。因为我认为:测试代码与生产代码一样有价值,指的是可读性,复杂性,可维护性等。理解10行代码,而不是30行代码,要容易得多。你可以相信我的经验。有经验我的意思是:我做错了很多...而且自我对过去的自己非常生气(懒惰):P。话虽如此:我更喜欢一个易于理解的测试案例而不是n db往返,从长远来看它便宜得多......