java-测试驱动开发-如何在实现代码不存在之前编写测试
我正在学习TDD,但由于采用起来并不简单,因此正在努力采用它。
我无法回答的问题是“如何在任何实现代码存在之前编写测试?”。
如果我们的目标类/目标方法/目标参数类型/目标返回类型不存在,
在测试中编写代码时指的是什么。 我们如何开始编写测试?
如果我们只能编写实际实现代码之前的测试方法名称,该测试将如何失败?
每个人都说为什么但不告诉怎么
我已经尽力找到了在生产代码之前编写测试的详细资源,但是,如果我错过了很好的资源,那么大多数资源都充满了陈词滥调。解释为什么TTD比着重于采用它的实践重要。
一个用例示例。
假设我们正在为大学开发软件,而用例是课程注册。
为简单起见,让我们将讨论限制在
方案:“一个学生每学期最多可以注册3门课程”
测试服务层和岛层。
伪码
ENROLL(studentId, courseId)
//check if student enrolled in less than 3 courses in the same semester as given courseId belongs in.
//if yes, enroll him/her.
//if not, return an error.
上面的实际实现可能跨越涉及服务,Dao等的几类。
请您能解释一下如何逐步测试驱动开发它吗? 如果要使用TDD来实现此功能,则如何逐步进行。
我希望这可以在将来帮助像我这样的许多斗争。
4个解决方案
43 votes
在与EnrollingService相同的软件包中在src / test / java中创建EnrollingServiceTest类
class EnrollingServiceTest {
private EnrollingService enrollingService;
@Before
public void init() {
enrollingService = new EnrollingService();
}
@Test
public void testEnroll() {
boolean result = enrollingService.enroll(1l, 1l);
assertTrue(result);
...
IDE(我假设您正在使用IDE)显示错误-EnrollingService不存在。
将光标指向EnrollService-IDE将提供创建类的功能-让它在src / main / java中创建
现在IDE说缺少enroll(long,long)方法-让IDE为您创建它。
现在,IDE不显示任何错误。 运行测试-失败。 去注册并开始实施逻辑
等等...
Evgeniy Dorofeev answered 2020-02-18T12:53:22Z
4 votes
当您专注于代码的预期行为而不是代码的实现时,这将变得更加清楚。 因此,根据您概述的情况,您可能会得出结论,必须在某个类中编写enroll()方法。 然后,您可以考虑如何测试该课程。
您首先要考虑课程的条件以及对课程的期望。 也许您可以识别出该类的某些不变式。 在这种情况下,要测试该类,您需要考虑违反该不变式的方式。
因此,假设:一个学生每学期最多可以注册3门课程,那么您可以考虑发生这种情况的方式。
学生已在指定学期内注册了0门课程,尝试注册一门课程,结果:注册成功; 现在,该学生已为该学期注册了1门课程。
学生在给定的学期注册了1门课程,尝试注册课程,结果:注册成功; 该学生现在已注册该学期的2门课程。
学生在给定的学期注册了3门课程,尝试注册一门课程,结果:失败(也许抛出异常?)
等
接下来,您实际编写这些测试。 这些都可以作为测试方法。 因此,测试方法将确保创建对象并按预期设置环境。 然后调用该方法,并将结果与预期结果进行比较。 如果您期望发生的事情确实发生了,那么测试就通过了。
现在,最初,由于您尚未编写方法,因此测试实际上不会通过。 但是,随着您开始编写代码,您的测试将开始通过,最终100%的测试将通过,此时您对自己的代码满足要求感到满意。
Vincent Ramdhanie answered 2020-02-18T12:54:20Z
3 votes
public void shouldNotEnrollInMoreThanFourClassesInASemester() {
Enroller enroller = new Enroller();
Student student = new Student();
Semester one = new Semester();
Semester two = new Semester();
Course geology = new Course(one);
Course architecture = new Course(one);
Course calculus = new Course(one);
Course sociology = new Course(one);
Course geometry = new Course(two);
assertOk(enroller.enroll(student, geology));
assertOk(enroller.enroll(student, architecture));
assertOk(enroller.enroll(student, calculus));
assertNotOk(enroller.enroll(student, sociology));
assertOk(enroller.enroll(student, geometry));
}
Carl Manaster answered 2020-02-18T12:54:36Z
1 votes
在您的方案中,您应该分别测试每个层,因此在测试服务层时模拟出dao。
当您第一次编写测试时,它不会编译,这意味着它会失败,但这很好,因为这些类不存在。
在您的示例中,最多应强制在哪一层注册3门课程? 那会影响您的测试方式。
首先编写测试将帮助您解决这些类型的问题。
如前所述,这对于确定性答案来说是开放式的,但是如果您开始编写测试,然后发布更新内容可能会有所帮助。
因此,编写您的dao测试,然后编写类和方法,以便对其进行编译,但在yiu完成实现之前,它应该仍然会失败。 您可能需要测试2,3,4类注册,并确保每个注册均正确失败,然后完成实现。
James Black answered 2020-02-18T12:55:22Z