机械设备asp企业网站源码下载,怎么免费推广自己网站,淮安市建设工程安全监督站网站,wordpress 防注册初级测试开发面试题自从我编写第一个单元测试以来已经有10年了。 从那时起#xff0c;我不记得我已经编写了成千上万的单元测试。 老实说#xff0c;我在源代码和测试代码之间没有任何区别。 对我来说是同一回事。 测试代码是源代码的一部分。 在过去的3-4年中#xff0c;我… 初级测试开发面试题 自从我编写第一个单元测试以来已经有10年了。 从那时起我不记得我已经编写了成千上万的单元测试。 老实说我在源代码和测试代码之间没有任何区别。 对我来说是同一回事。 测试代码是源代码的一部分。 在过去的3-4年中我与多个开发团队合作并且有机会查看了大量的测试代码。 在这篇文章中我总结了经验不足的开发人员在编写单元测试时通常会犯的最常见错误。 让我们看下面的类的简单示例该类收集注册数据对其进行验证并执行用户注册。 显然该方法非常简单其目的是演示单元测试的常见错误而不是提供功能齐全的注册示例 public class RegistrationForm {private String name,email,pwd,pwdVerification;// Setters - Getters are ommitted public boolean register(){validate();return doRegister();}private void validate () {check(name, email);check(email, email);check(pwd, email);check(pwdVerification, email);if (!email.contains()) {throw new ValidationException(name cannot be empty.);} if ( !pwd.equals(pwdVerification))throw new ValidationException(Passwords do not match.);}private void check(String value, String name) throws ValidationException {if ( value null) {throw new ValidationException(name cannot be empty.);}if (value.length() 0) {throw new ValidationException(name is too short.);}}private boolean doRegister() {//Do something with the persistent contextreturn true;} 这是注册方法的相应单元测试有意显示单元测试中最常见的错误。 实际上我已经看过很多次非常相似的测试代码所以这不是我所说的科幻小说 Testpublic void test_register(){RegistrationForm form new RegistrationForm();form.setEmail(Al.Pacinoexample.com);form.setName(Al Pacino);form.setPwd(GodFather);form.setPwdVerification(GodFather);assertNotNull(form.getEmail());assertNotNull(form.getName());assertNotNull(form.getPwd());assertNotNull(form.getPwdVerification());form.register();} 现在此测试显然将通过开发人员将看到绿灯所以竖起大拇指 让我们转到下一个方法。 但是此测试代码有几个重要问题。 在我拙见中第一个是单元测试的最大误用是测试代码没有充分测试寄存器方法。 实际上它仅测试许多可能路径中的一个。 我们确定该方法将正确处理空参数吗 如果电子邮件中不包含字符或密码不匹配该方法将如何工作 开发人员倾向于只为成功的路径编写单元测试而我的经验表明代码中发现的大多数错误都与成功的路径无关。 一个非常好的规则要记住的是对于每一个方法你需要N个测试其中N等于在圈复杂度将所有私有方法调用的圈复杂度的方法。 接下来是测试方法的名称。 为此我部分归咎于所有这些现代IDE它们自动为测试方法如示例中的方法生成愚蠢的名称。 测试方法的命名应向读者解释将要测试的内容和条件 。 换句话说它应该描述正在测试的路径。 在我们的情况下更好的名称可能是 should_register_when_all_registration_data_are_valid。 在本文中您可以找到几种命名单元测试的方法但是对我来说“应该”模式最接近人类语言并且在阅读测试代码时更容易理解。 现在让我们看一下代码的内容。 有几个断言这违反了每个测试方法应断言一件事的规则 。 这一个断言了四4个RegistrationForm属性的状态。 这使得测试更加难以维护和阅读哦是的测试代码应该像源代码一样可维护和可读。请记住对我来说它们之间没有区别并且很难理解测试的哪一部分失败。 此测试代码还声明了setter / getter。 这真的有必要吗 为了回答这个问题我将引用罗伊·奥什罗夫Roy Osherove的名言“ 单元测试的艺术 ” 属性Java中的getter / setter是很好的示例代码通常不包含任何逻辑也不需要测试。 但是要当心在属性中添加任何检查之后您将要确保逻辑已经过测试。 在我们的案例中设置器/获取器中没有业务逻辑因此这些断言完全没有用。 此外他们错了因为他们甚至没有测试安装员的正确性。 想象一下一个邪恶的开发人员将getEmail方法的代码更改为始终返回常量String而不是email属性值。 该测试仍将通过因为它断言setter不为null并且未断言期望值。 因此这可能是您要记住的一条规则。 断言方法的返回值时请始终尝试尽可能具体 。 换句话说除非您不关心实际的返回值否则请尽量避免使用assertIsNullassertIsNotNull。 我们正在查看的测试代码的最后但并非最不重要的问题是从未断言正在测试的实际方法 寄存器 。 它在测试方法内部被调用但是我们从不评估其结果。 这种反模式的变化甚至更糟。 在测试用例中甚至不会调用被测方法。 因此请记住 不仅应该调用被测方法而且还应该始终声明预期结果即使它只是一个布尔值 。 有人可能会问“无效方法是什么”。 好的问题但这是另一次讨论–可能是另一篇文章但是为您提供一些提示测试void方法可能会掩盖不好的设计或者应该使用验证方法调用的框架例如Mockito.Verify 来完成。 作为奖励您应该记住这是一条最终规则。 想象一下 doRegister实际上已经实现并且对外部数据库做了一些实际的工作。 如果某个本地环境中未安装数据库的开发人员尝试运行测试将会发生什么情况。 正确 一切都会失败。 确保测试即使从仅可访问代码和JDK的最垃圾终端运行也具有相同的行为 。 没有网络没有服务没有数据库没有文件系统。 没有 翻译自: https://www.javacodegeeks.com/2014/09/common-mistakes-junior-developers-do-when-writing-unit-tests.html初级测试开发面试题