我对TDD非常陌生,尤其是做TFD。我还没有写任何代码,我想在结合TDD开发所有东西之前先写一个测试。我需要你的洞察力。我好像在复制粘贴我的测试代码。我制作了我的"伪"用户故事供我练习。我要转述一下,因为这是一个实际的个人项目,所以请耐心等待
"用户可以搜索标签">
我有一个UI,可以添加和搜索标签。我用最小的设计使它有点保守。我有一个按钮,可以在添加/搜索字符串之间切换。我有一个CardView
来表示这一点,CardView
是列表的一部分(就像Facebook(。现在我想测试一下,当用户按下按钮时,卡片上的内容会变为搜索模式。我对如何做到这一点很有想法,但每次测试都复制粘贴我的测试代码有点困扰我
这是我的测试:
public class TagListActivityTest
{
@Test
public void shouldHaveAddTagCard()
{
// User tapped to expand the card
onView(withId(R.id.edittext_description_minimized))
.perform(click());
// User sees the expanded card
onView(withId(R.id.linearlayout_add_note_maximize))
.check(matches(isDisplayed()));
// User sees the expanded card's quick action buttons
onView(withId(R.id.relativelayout_quick_action_button))
.check(matches(isDisplayed()));
// User clicks the add tag button
onView(withId(R.id.imagebutton_tag))
.perform(click());
// User sees the tag list
onView(withId(R.id.coordinatorlayout_tag_list))
.check(matches(isDisplayed()));
// User sees the add tag card
onView(withId(R.id.cardview_add_tag))
.check(matches(isDisplayed()));
}
@Test
public void shouldToggleToSearch()
{
// I am going to do the exact same thing as shouldHaveAddTagCard
// starting from my parent activity until here...
onView(withId(R.id.edittext_description_minimized))
.perform(click());
onView(withId(R.id.linearlayout_add_note_maximize))
.check(matches(isDisplayed()));
onView(withId(R.id.relativelayout_quick_action_button))
.check(matches(isDisplayed()));
onView(withId(R.id.imagebutton_tag))
.perform(click());
onView(withId(R.id.coordinatorlayout_tag_list))
.check(matches(isDisplayed()));
}
}
TagListActivity
源自父活动。在通过TagListActivity
之前,你必须做一些事情,我已经为它编写了测试。所以当我测试TagListActivity
时,我必须首先进入应用程序的主屏幕,然后从那里导航,正如你从我的测试过程shouldHaveAddTagCard
中看到的那样。这是我的问题,我必须一遍又一遍地写那个程序。因此,当我想测试shouldToggleSearch
时,我必须从父活动开始,再次编写这些测试,直到达到TagListActivity
。我想我做错了什么。
所以我的问题是:
- 当存在已知的用户操作过程时,我如何组织此操作。我已经按照程序编写了测试,以确保它符合我的要求未来
- 没有。1让我觉得自己做的事情有问题。我正在测试每个动作(即用户添加标签,用户搜索标签,用户删除标签(。所以预处理我之前做的
user can add tags
和user can search tag
是一样的,我已经在我真正测试之前复制粘贴这些预处理程序
此外,我似乎无法从这里讨论的测试方法中调用测试方法。我正在考虑重用测试代码,但这是不可取的。
做事正确吗?有什么想法吗?
老实说,如果这是您第一次做TDD,那么您的测试看起来非常好。
减少重复
您可以在每次测试之前使用@Before
注释来执行一些代码。在你的情况下,它可能看起来像这样:
// this method will be executed before each test
@Before
public void clickOnEditTextDescription() {
onView(withId(R.id.edittext_description_minimized))
.perform(click());
// put as much set up code in here as you need
}
请记住,一般情况下,不应在@Before
方法中进行任何断言。它仅用于设置代码。
但这总是一件好事吗
@Before
方法很好,但是请记住,复制和粘贴测试代码并不总是坏事。这与生产代码不同。在生产代码中,您不希望重复,因为任何给定的业务逻辑都应该只存在于一个地方。然而,在测试代码中,每个测试都需要与所有其他测试完全独立。如果在测试代码中消除了所有的重复,那么在不破坏所有测试的情况下更改共享代码将非常困难。此外,您的测试将更难阅读,因为您必须不断引用共享代码。
我建议你对DAMP(描述性和有意义的短语(和DRY(不要重复(做一些研究。DAMP与单元测试更相关,并且允许您有时重复自己。DRY与生产代码更相关。以下答案很好地解释了这一点:
https://stackoverflow.com/a/11837973/6816469