Open rainit2006 opened 7 years ago
MAT (Memory Analyzer Tool) Heap Allocated確認できる、メモリリーク時に利用できるツール
Stetho Network状況を確認できるツール. Android用のDebug Bridgeで、これを使うと Chrome Developer Toolsの一部を利用して、Javascriptと同様にNetwork状況を確認できるツールです。
和JUnit3的不同点:
local unit test Located at module-name/src/test/java/. These tests run on the local JVM and do not have access to functional Android framework APIs. android framework に依存しないテスト。java vm で実行されるため、他のAndroidOSに依存するテストに比べて高速。
Instrumented tests Located at module-name/src/androidTest/java/. These are all tests that must run on an Android hardware device or an Android emulator.
Mock以及Mockito https://zhuanlan.zhihu.com/p/25982343
所谓的mock就是创建一个类的虚假的对象,在测试环境中,用来替换掉真实的对象,以达到两大目的: 1,验证这个对象的某些方法的调用情况,调用了多少次,参数是什么等等 2,指定这个对象的某些方法的行为,返回特定的值,或者是执行特定的动作 要使用Mock,一般需要用到mock框架,这篇文章我们使用Mockito这个框架
使用Mockito,验证一个对象的方法调用情况的姿势是: Mockito.verify(objectToVerify).methodToVerify(arguments); 其中,objectToVerify和methodToVerify分别是你想要验证的对象和方法。
如果你想验证一个对象的某个方法得到了多次调用,只需要将次数传给Mockito.times()就好了。 Mockito.verify(mockUserManager, Mockito.times(3)).performLogin(...); //验证mockUserManager的performLogin函数得到了三次调用。
很多时候你并不关心被调用方法的参数具体是什么,或者是你也不知道,你只关心这个方法得到调用了就行。这种情况下,Mockito提供了一系列的any方法,来表示任何的参数都行: Mockito.verify(mockUserManager).performLogin(Mockito.anyString(), Mockito.anyString()); anyString()表示任何一个字符串都可以。null?也可以的! 类似anyString,还有anyInt, anyLong, anyDouble等等。anyObject表示任何对象,any(clazz)表示任何属于clazz的对象。
另外, 指定mock对象的某个方法,让它返回特定值的写法如下: Mockito.when(mockObject.targetMethod(args)).thenReturn(desiredReturnValue);
//当调用mockValidator的verifyPassword方法时,返回true,无论参数是什么 Mockito.when(validator.verifyPassword(anyString())).thenReturn(true);
函数里包含callback时的验证方法: 这种指定mock对象执行特定的动作的写法如下: Mockito.doAnswer(desiredAnswer).when(mockObject).targetMethod(args); 传给doAnswer()的是一个Answer对象(callback),我们想要执行什么样的动作,就在这里面实现。
Mockito.doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
//这里可以获得传给performLogin的参数
Object[] arguments = invocation.getArguments();
//callback是第三个参数
NetworkCallback callback = (NetworkCallback) arguments[2];
callback.onFailure(500, "Server error");
return 500;
}
}).when(mockUserManager).performLogin(anyString(), anyString(), any(NetworkCallback.class));
当然,使用Mockito.doAnswer()需要创建一个Answer对象,这有点麻烦,代码看起来也繁琐,如果想简单的指定目标方法“什么都不做”,那么可以使用Mockito.doNothing()。如果想指定目标方法“抛出一个异常”,那么可以使用Mockito.doThrow(desiredException)。如果你想让目标方法调用真实的逻辑,可以使用Mockito.doCallRealMethod()。
SampleA をテスト対象のクラスにします。
public class SampleA {
private SampleC sampleC;
public String createName() {
Integer id = sampleC.getId();
Integer price = sampleC.getPrice(id);
String ret = "id:" + id + " price:" + price;
return ret;
}
}
SampleC のクラス
public class SampleC {
public Integer getId() {
return 1 + 2;
}
public Integer getPrice(Integer id) {
Integer price = id * 100;
return price;
}
}
@Spyを使って、SampleAのテストをします。
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
public class MockitoSampleTest {
@Spy
private SampleC sampleCMock = new SampleC();
@InjectMocks
private SampleA sampleA = new SampleA();
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testVerify() {
// モックを用意する。
// getPrice()メソッドのみをモック化します。
doReturn(555).when(sampleCMock).getPrice((Integer)anyObject());
// テスト対象のクラスを実行します。
String ret = sampleA.createName();
// 戻り値を確認する。
assertEquals("id:3 price:555", ret);
}
}
サンプルソースでは、 getPrice()メソッドは、モック化しています。 getId()メソッドは、モック化していません。
Dagger2
LoginActivity所需要的,不过是一个LoginPresenter而已,然而它却需要知道LoginPresenter的Dependency是什么,LoginPresenter的Dependency的Dependency又是什么,然后new一堆东西出来。而且可以预见的是,这个app的其他地方也需要这里的OkHttpClient、Retrofit、SharedPreference、UserManager等等dependency,因此也需要new这些东西出来,造成大量的代码重复,和不必要的object instance生成。 如果能达到这样的效果,那该有多好:我们只需要在一个类似于dependency工厂的地方统一生产这些dependency,以及这些dependency的dependency。所有需要用到这些Dependency的client都从这个工厂里面去获取。而且更妙的是,一个client(比如说LoginActivity)只需要知道它直接用到的Dependency(LoginPresenter),而不需要知道它的Dependency(LoginPresenter)又用到哪些Dependency(UserManager和PasswordValidator)。系统自动识别出这个依赖关系,从工厂里面把需要的Dependency找到,然后把这个client所需要的Dependency创建出来。
DI模式的client和dependency DI模式里面有两个概念:Client和Dependency。假如你的代码里面,一个类用到了另外一个类,那么前者叫Client,后者叫Dependency。
注入(DI)的常见实现方式 https://zhuanlan.zhihu.com/p/26030341 1, setter injection 2, argument injection
public class LoginPresenter {
//这里,LoginPresenter不再持有UserManager的一个引用,而是作为方法参数直接传进去
public void login(UserManager userManager, String username, String password) {
//... some other code
userManager.performLogin(username, password);
}
}
3,Constructor Injection 是将Dependency作为Client的构造方法的参数传递进去:
public class LoginPresenter {
private final UserManager mUserManager;
//将UserManager作为构造方法参数传进来
public LoginPresenter(UserManager userManager) {
this.mUserManager = userManager;
}
public void login(String username, String password) {
//... some other code
mUserManager.performLogin(username, password);
}
}
Annotation @Module for the classes whose methods provide dependencies @Provides for the methods within @Module classes @Inject to request a dependency (a constructor, a field, or a method) @Component is a bridge interface between modules and injection
在dagger2里面,负责生产这些Dependency的统一工厂叫做 Module ,所有的client最终是要从module里面获取Dependency的,然而他们不是直接向module要的,而是有一个专门的“工厂管理员”,负责接收client的要求,然后到Module里面去找到相应的Dependency,提供给client们。这个“工厂管理员”叫做 Component。基本上,这是dagger2里面最重要的两个概念。
link.zhihu.com/?target=http%3A//chriszou.com/2016/05/10/android-unit-testing-di-dagger.html
Live2D http://sites.cybernoids.jp/cubism2/beginner-tutorial/08/beginner-tutorial
Google Guava Googleが開発しているOSSのjava core libraryで、Googleの多くのJavaベースのプロジェクトで使用されており、 Java 1.5 以上で使用できる。 Apache Commons の Lang、Collectionsなどに替わる機能を提供していて、パッケージ名を見れば大体の機能について想像がつくと思います。 com.google.common.annotations com.google.common.base com.google.common.cache com.google.common.collect com.google.common.escape com.google.common.eventbus com.google.common.hash com.google.common.html com.google.common.io com.google.common.math com.google.common.net com.google.common.primitives com.google.common.reflect com.google.common.util.concurrent
ToSpeakG3 音声合成ミドルウェア. https://toshiba.semicon-storage.com/jp/product/software-ip/tospeak.html
Andorid的单元测试介绍系列 https://zhuanlan.zhihu.com/p/25882260 https://zhuanlan.zhihu.com/p/25882966 https://zhuanlan.zhihu.com/p/25936894 https://zhuanlan.zhihu.com/p/25982343 https://zhuanlan.zhihu.com/p/26030341 http://chriszou.com/2016/05/10/android-unit-testing-di-dagger.html