8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?
Unit Test
Start
简单了解一下,如何依赖 Junit 进行 Java 代码的单元测试。依旧如何借助 Robolectric 进行 Android 方面的单元测试,主要是 Context 的获取。最后就网络请求的单元测试,简单叙述一下。
JUnit依赖1testImplementation 'junit:junit:4.12'example1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class{
private static final String TAG = "Tools";
public static String getCurrentTime(){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss", Locale.CHINA);
Date curDate = new Date(System.currentTimeMillis());
return simpleDateFormat.format(curDate);
}
public static String getCurrentTime(long tempStap){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年", Locale.CHINA);
Date curDate = new Date(tempStap);
return simpleDateFormat.format(curDate);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class ToolsUnitTest{
public static void setUp(){
System.out.println( ToolsUnitTest.class.getSimpleName()+ "=====单元测试开始");
}
@AfterClass
public static void end(){
System.out.println( ToolsUnitTest.class.getSimpleName()+ "=====单元测结束");
}
@Test(expected = NullPointerException.class)
public void getCurrentTimeTest(){
assertNotEquals("1111",Tools.getCurrentTime());
assertEquals("2019年",Tools.getCurrentTime(System.currentTimeMillis()));
}
}
执行顺序: @BeforeClass –> @Before –> @Test –> @After –> @AfterClass可用 API
都是 Assert 的静态方法,对有返回值的方法,用断言非常好用,你甚至可以测试异常高级用法@RunWith(Parameterized.class) 参数化
assertThat用法
@Rule用法问题来了1public static String getAppVersion(Context mContext){ ... }
Android 中的 context 怎么搞 ?
Robolectric配置依赖1
2
3
4testImplementation 'androidx.test:core:1.2.0'
testImplementation 'androidx.test:rules:1.2.0'
testImplementation 'androidx.test.espresso:espresso-core:3.2.0'
testImplementation 'org.robolectric:robolectric:4.3'允许 robolectric 读取 assets、resources 和 manifests,在 build.gradle 中添加
一定要添加以下配置,否则将导致单元测试运行异常
一定要添加以下配置,否则将导致单元测试运行异常
一定要添加以下配置,否则将导致单元测试运行异常1
2
3
4
5testOptions {
unitTests {
includeAndroidResources = true
}
}在 gradle.properties 中添加1android.enableUnitTestBinaryResources=true
example1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25@RunWith(RobolectricTestRunner::class)
@Config(sdk = [27])
class RobolectricUnitTest{
@Test
fun assertContext() {
val context = ApplicationProvider.getApplicationContext()
val version = AppUtils.getAppVersion(context)
// 单元测试,也可以打印日志
println("version ==$version")
assertEquals("1.0", version)
}
companion object {
fun setup() {
// for Fresco
SoLoader.setInTestMode()
}
}
}
单元测试也可以用 Kotlin 写,😬😬😬
Context 是什么 ?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29@RunWith(RobolectricTestRunner.class)
@Config(sdk = 28, manifest = Config.NONE)
public class ContextTest{
@Test
public void useContextTest() throws Utils.SystemUtilsException{
Context context = ApplicationProvider.getApplicationContext();
System.out.println("context ===" + context.getClass().getName());
assertEquals(Constants.PACKAGE_NAME, Utils.getPackageName(context));
assertEquals(Constants.PACKAGE_VERSION, Utils.getPackageVersionName(context));
}
@Test
public void screenInfoTest(){
Context context = ApplicationProvider.getApplicationContext();
Resources resources = context.getResources();
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
float density = displayMetrics.density;
float width = displayMetrics.widthPixels;
float height = displayMetrics.heightPixels;
System.out.println("density==" + density);
System.out.println("width ==" + width);
System.out.println("height ==" + height);
}
}
-output1
2
3density==1.0
width ==320.0
height ==470.0可能遇到的问题
Application 中某些方法无法被初始化,比如 Fresco,详见
及解决方案。
Robolectric 很强大,可以在不使用真机及模拟器的情况下,进行 UI 测试
Robolectric 可以认为是一个虚拟的模拟器
网络测试网络测试有以下困难请求结果是异步返回的,无法直接进行断言,需要进行同步转换
后端会做 cookie 和 headers 的校验,Robolectric 只是模拟器,请求时没有这些信息。
对 okhttp 添加 intercept ,拦截返回值,进行任意返回结果,测试后续逻辑。simple1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18@Test
public void netTest(){
final Retrofit mRetrofit = initRetrofit();
GankApi mGankApi = mRetrofit.create(GankApi.class);
Observable mAndroidObservable = mGankApi.getData("10/1");
mAndroidObservable.subscribe(gankAndroid -> {
doAssert(gankAndroid.getResults().get(0));
}, throwable -> System.out.println("fail"));
}
private void doAssert(GankAndroid.ResultsEntity entity){
assertEquals("5d423ff19d2122031ea52264", entity.get_id());
assertEquals("web", entity.getSource());
assertEquals("Android", entity.getType());
assertEquals("潇湘剑雨", entity.getWho());
}
这个就可以对网络请求回来的数据,进行各种业务逻辑的测试了。
但是也可以添加 interceptor ,创建特定的返回结果添加 Interceptor 拦截返回结果,方便测试后续逻辑。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18@Test
public void netWithInterceptTest(){
String json = "404";
SimpleIntercept errorIntercept = new SimpleIntercept(json, 404);
// SimpleIntercept successIntercept = new SimpleIntercept(json, HTTP_OK);
final Retrofit mRetrofit = initRetrofit(errorIntercept);
GankApi mGankApi = mRetrofit.create(GankApi.class);
Observable mAndroidObservable = mGankApi.getData("10/1");
mAndroidObservable.subscribe(gankAndroid -> {
},
throwable -> {
// for example
assertEquals("HTTP 404 404", throwable.getMessage());
});
} SimpleIntercept1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25public class SimpleIntercept implements Interceptor{
private static final String APPLICATION_JSON = "application/json";
private String expectedResult;
private int code;
public SimpleIntercept(@NonNull String expectedResult, int code){
this.expectedResult = expectedResult;
this.code = code;
}
@Override
public Response intercept(Chain chain){
Response response = new Response.Builder()
.code(code)
.message(expectedResult)
.request(chain.request())
.protocol(Protocol.HTTP_1_1)
.body(ResponseBody.create(MediaType.parse(APPLICATION_JSON), expectedResult))
.addHeader("content-type", APPLICATION_JSON)
.build();
return response;
}
}
参考资料