每个人都建议遵循MVP或MVVM模式以保持代码的可读性和可测试性.现在我有疑问.现在,我正在学习单元测试,并以一种正式的方式编写代码.不使用任何模式.现在我的问题是,我可以像下面那样测试我的代码吗? 我的主要活动: public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public boolean testMethod(int value){
return value== 5?true:false;
}
}
我的单元测试课: @RunWith(MockitoJUnitRunner.class)
public class ExampleUnitTest {
MainActivity mainActivity = new MainActivity();
@Test
public void testMethod(){
boolean result = mainActivity.testMethod(5);
assertEquals(true,result);
}
}
在运行测试时,我没有收到任何错误或问题.那么这是正确的测试方法吗?还是如果我遵循这种方法会发生什么?我也开始将代码迁移到MVP模式,但是我想清除我的疑问.请让我知道为什么我不遵循单元测试的正式编码的原因. 解决方法: 您的简单示例之所以有效,是因为被测试的代码实际上并不依赖于Activity类或任何UI状态.尝试针对实际上取决于UI状态的代码编写测试,例如 public boolean verifyInput() {
EditText edit = findViewById(R.id.edit1);
return edit.getText().toString().startsWith("0");
}
如果继续走这条路,您会发现以下事情发生: >您的Activity类将变得越来越大(神对象反模式). >实际依赖UI状态的代码(您的示例并不如此)无法使用简单的单元测试编写,因此需要Android仪表测试.即测试将无法再在您的主机上执行,而必须在设备上执行,并且需要将Activity设置为正确的状态. >由于处理UI动作和状态需要进行所有繁重的工作,因此仪表测试通常较慢并且可能会很不稳定.您将在测试运行中收到假阴性. >测试方法将变得更加复杂,因为它们必须使UI进入正确的状态以测试逻辑.
现在,有一个简单的解决方案.将核心逻辑与UI逻辑分开.使处理UI的代码尽可能简单,并将(复杂的)核心逻辑移到单独的类中.突然,您有了一个带有方法的第二类,这将使您更容易推理和编写测试.第二类也将匹配您的应用程序用户将能够执行的操作. 一段时间后,您将也想拆分第二类,因为您会注意到某些方法子集与另一方法子集无关.因此,您将保持模块化和精心设计,以使开发人员更容易理解和使用代码.这是MVP,MVVM等模式变得方便的时候. 请注意,我不建议您立即使用MVVM之类的模式.如果您刚刚开始学习编程,软件开发或Android,那么完全可以做自己的事.您将通过体验这些“痛点”来学习,这是我们很多人已经遇到的,那时您将开始寻找改进之处,以及为什么其他人建议使用特定的模式或最佳实践.
|