java当中怎么测试异步接口【杭州多测师_王sir】【杭州多测师】
测试是软件发布的重要环节,单元测试在实际开发中是一种常用的测试方法,java单元测试主要用junit,最新是junit5,本人开发一般用junit4。因为单元测试能够在软件模块组合之前尽快发现问题,所以实际开发中投入产出比很高。实际使用难免会遇到异步操作的接口测试,最常用的情景是别人家的SDK封装了异步处理,需要用测试用例来验证SDK的流程,顺便测试参数的处理情况。由于异步testcase的会在调用后立即返回,异步线程执行完之前test线程已经结束了,无法验证测试最终结果。我们可以通过同步锁方法把异步接口转换为同步处理流程。
一、什么是单元测试?
单元测试是对软件最小实现单元进行的一种测试,例如C语言的函数,C++的类,java的类等。java有一套单元测试框架junit,Android中有AndroidTestCase等等。我们可以用junit对java函数,类,模块接口进行测试。
二、java单元测试教程
对于单元测试的教程网上有好多,这里就不再重复阐述了。
eclipse单元测试==》http://tonl.iteye.com/blog/1948869
gradle构建junit单元测试教程 ==》http://www.jianshu.com/p/e4e99b62a203
三、如何处理异步类型的单元测试
1. 能够获取Thread句柄的异步类型
对于有java thread句柄的测试类型,我们使用使用Thread.join函数等待线程执行完毕。
@Test public void testExplicitThread() { System.out.println("testExplicitThread"); Thread thread = new Thread() { @Override public void run() { System.out.println("thread start."); try { for (int i = 0; i < 5; i++) { System.out.println("progress: " + i); sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("thread finish."); } } }; thread.start(); try { thread.join(); // 等待线程执行完毕 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("testExplicitThread exit"); }
测试用例输出:
testExplicitThread
thread start.
progress: 0
progress: 1
progress: 2
progress: 3
progress: 4
thread finish.
testExplicitThread exit
2. 没有thread句柄的异步单元测试
因为没有thread句柄,所以无法使用 join 函数。只能手动操作同步锁对异步接口进行同步
Object.wait 当前线程进入等待状态,直到其他线程调用 notify 或者 notifyAll 函数唤醒。
具体实现如下:
package com.duoceshi.test; import org.junit.jupiter.api.Test; public class ThreadNotifyAll { /** * 回调接口 */ interface Callback { void onStart(); void onProgress(int progress); void onFinish(); } /** * 异步方法 */ static class AsyncDemo { private int len = 0; private Callback callback = null; public AsyncDemo(int len, Callback cb) { this.len = len; this.callback = cb; } public void doJob() { new Thread() { @Override public void run() { if (null != callback) { callback.onStart(); } try { for (int i = 0; i < len; i++) { if (null != callback) { callback.onProgress(i); } sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } finally { if (null != callback) { callback.onFinish(); } } } }.start(); } } private Object mLock = new Object(); // 同步锁 private int mCount = 0; // 加解锁条件 @Test public void testBlindCallback() { System.out.println("testBlindCallback"); Callback cb = new Callback() { public void onStart() { System.out.println("onStart"); } public void onProgress(int progress) { System.out.println("onProgress: " + progress); } public void onFinish() { System.out.println("onFinish"); synchronized (mLock) { mCount = 0; mLock.notifyAll(); // 回调执行完毕,唤醒主线程 } } }; System.out.println("before AsyncDemo doJob"); AsyncDemo demo = new AsyncDemo(5, cb); demo.doJob(); synchronized (mLock) { mCount = 1; // 设置锁条件 while (mCount > 0) { try { mLock.wait(); // 等待唤醒 } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println("after AsyncDemo doJob"); } }
testBlindCallback
before AsyncDemo doJob
onStart
onProgress: 0
onProgress: 1
onProgress: 2
onProgress: 3
onProgress: 4
onFinish
after AsyncDemo doJob
处理方法就是在测试线程执行异步接口后进入wait,等待回调退出接口(onFinish)唤醒test线程。
原文地址:http://t.zoukankan.com/111testing-p-11111613.html