既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
我们新建android项目的时候,系统除了会给我们建立好开发的目录,同时也新建了测试用的目录,如图:
可以看到,androidTest顾名思义,是需要android环境的测试,需要连接android设备,不能直接build运行;
test是java测试,这里我们用的是JUnit,所以可以直接在IDE里面运行即可,不需要额外的android设备。
==============================================================
关注几个关键的Annotation,@Before表示初始化的一些操作,@Test表示需要测试验证方法。
public class DemoTest {
@Before
public void setUp() throws Exception {
}
@Test
public void isEmpty() {
assertEquals(true, “”.equals(“”));
}
}
适用范围:
逻辑验证,算法等。
运行的时候,在方法的这一行点击鼠标右键,可以选择Run或者Debug。
=================================================================
espresso框架主要用来解决重复性的UI操作,所以是在androidTest目录下面。
@RunWith(AndroidJUnit4.class)
@LargeTest
public class WeatherActivityTest {
@Rule
public ActivityTestRule mActivityRule = new ActivityTestRule<>(
WeatherActivity.class);
@Test
public void runClick(){
onView(withText(“点击获取城市感冒指数”)).perform(click());
onView(withId(R.id.wendu)).check(matches(withText(“点击获取城市今天温度”)));
}
}
注意关键的annotation,@RunWith(AndroidJUnit4.class)开头,@Rule规则,@Test需要测试的方法。还有需要添加
androidTestImplementation ‘com.android.support.test:rules:1.0.2’
引用。
上面runClick里面的测试,一个表示text内容为"点击获取城市感冒指数"则执行点击,另一个表示找到R.id.wendu的控件,然后看它是否text内容为"点击获取城市今天温度"。
================================================================
这两个都是Android测试框架,主要是可以脱离Android设备调试环境,在纯Java环境下面完成Android测试用例。也就是说不像espresso那样需要连接一台android设备了,我们可以像运行JUnit那样来运行android测试用例。
在junit单元测试中,需要手动构造测试中对对象的依赖。如A对象方法依赖B对象方法,在测试A对象的时候,我们需要首先构造出B对象,这样子增加了测试的难度,如果依赖过多,相应地也增大了编写测试用例的难度。
Mockito是一个Java开源的测试框架,Mockito在测试中尝试移除我们传统JUnit单元测试中使用的Expect方式,这样子有效降低代码的耦合。使得我们只测试我们需要的方法和类,而不需过多的考虑依赖类。
Mockito不能模拟final类、匿名类和Java基本类型;对于final方法和static方法,不能对其 when(…).thenReturn(…) 操作。
另外mock对象,大多都需要植入到应用代码中,从而进行verify(…)操作;但应用代码中不一定有相应的set方法,如果要植入,就需要为了测试添加应用代码。也就是说A对象中需要增加一个set方法专门用来引入mock过的B对象,这样也就是说需要为一个测试用例在原来的对象中增加set方法,这样也是有点复杂。后面我们举例可以用反射来解决这个问题。
@Test
public void testList() {
List mockedList = mock(List.class);
mockedList.add(“one”);
mockedList.clear();
verify(mockedList).add(“one”);
verify(mockedList).clear();
}
适用范围:
解决依赖问题,一般用来测试费生命周期相关的类,比如MVP的P层和M层。如果涉及到生命周期相关的,这需要用到下面的Robolectric测试框架。
====================================================================
Robolectric是一款专门针对Android SDK的测试框架,我们只需要在Java环境中即可运行。
public class WeatherActivityTest {
private WeatherActivity activity;
private WeatherPresenter presenter;
@Before
public void setUp() {
activity = Robolectric.setupActivity(WeatherActivity.class);
}
@Test
public void testToSettingPage(){
activity.toSettingPage();
Intent expectedIntent = new Intent(activity, SettingActivity.class);
Intent actualIntent = ShadowApplication.getInstance().getNextStartedActivity();
Assert.assertEquals(expectedIntent.getComponent(), actualIntent.getComponent());
}
}
通过Robolectric.setupActivity启动一个activity,当然这个activity不会真正的启动。
通过testToSettingPage方法,我们测试activity的toSettingPage方法启动后,是否真的去了SettingActivity这个页面。
适用范围:
有android生命周期的,当然Robolectric功能点不知这些,有兴趣的可以去官网看看:http://robolectric.org/
=============================================================
以上四个测试框架各有优点,我们实际应用的时候往往是几种框架一并使用。
比如android开发过程中,我们为了避免使用到android设备来测试,所以我们会用到Robolectric框架,同时也会用到JUnit和Mockito,下面我们看下具体的例子:
@RunWith(RobolectricTestRunner.class)
@Config(sdk = 28)
public class WeatherActivityTest {
private WeatherActivity activity;
private WeatherPresenter presenter;
@Before
public void setUp() {
activity = Robolectric.setupActivity(WeatherActivity.class);
presenter = mock(WeatherPresenter.class);
activity.setPresenter(presenter);//如果不用这种方式就要用反射获取private成员变量
}
@Test
public void testGanmaoClick() {
Button ganmao = activity.findViewById(R.id.ganmao);
ganmao.performClick();
verify(presenter).getGanmao();
//如果不用activity.setPresenter(presenter)则使用下面代码
// try {
// Field field = WeatherActivity.class.getSuperclass().getDeclaredField(“mPresenter”);
// field.setAccessible(true);
// field.set(activity, presenter);
// ganmao.performClick();
// verify(presenter).showTest2();
// } catch (Exception e) {
// //error
// }
// verify(presenter).showTest1();
}
@Test
public void testWenduClick() {
Button wendu = activity.findViewById(R.id.wendu);
wendu.performClick();
assertThat(wendu.getText().toString(), is(“点击获取城市今天温度”));
assertEquals(“验证温度”, wendu.getText().toString(), “点击获取城市今天温度”);
}
@Test
public void testShadows() {
TextView wendu = activity.findViewById(R.id.wendu);
ShadowTextView stv = Shadows.shadowOf(wendu);
assertEquals(“验证温度示”,stv.innerText(),“点击获取城市今天温度”);
}
@Test
public void testToSettingPage(){
activity.toSettingPage();
Intent expectedIntent = new Intent(activity, SettingActivity.class);
Intent actualIntent = ShadowApplication.getInstance().getNextStartedActivity();
Assert.assertEquals(expectedIntent.getComponent(), actualIntent.getComponent());
}
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
.getComponent(), actualIntent.getComponent());
}
[外链图片转存中…(img-v0sXEGhv-1715723338176)]
[外链图片转存中…(img-GhQrir5w-1715723338176)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!