Mrli
别装作很努力,
因为结局不会陪你演戏。
Contacts:
QQ博客园

软件测试大赛

2019/11/02 环境配置 Java 软件测试
Word count: 3,124 | Reading time: 13min

软件测试大赛

初学流程

  1. 首先了解比赛,查看帮助文档平台帮助
  2. 然后在工具下载中下载工具、eclipse插件
  3. 最后根据教程中将插件安装好即可

移动应用测试开发

环境配置

配置Java环境

略,见Java 开发环境配置_菜鸟教程

安装ADB

1.菜单——>Tools——>Settings,将Server地址为 mirrors.neusoft.edu.cn, 端口 80 ,并且在Others里勾选 Force https://…,最后一定要选择菜单——>Packages菜单——>Reload

注:其他可用的镜像

2.把 Android SDK 路径下的tools 和 platform-tools 两个目录路径加入到系统环境变量 Path

3.在终端(cmd)输入命令 adb ,回车,输出 adb 版本和帮助信息说明环境配置成功

安装Node.js

安装Appium

1)下载安装文件: http://pan.baidu.com/s/1jGvAISu Windows 下载zip文件,MAC请下载dmg
2)直接双击appium-installer.exe文件安装就好(务必记住安装路径),桌面会生成一个Appium的图标
此时已经可以通过Appium在桌面快捷方式启动Appium桌面应用程序,并点击应用程序右上侧启动状按钮启动Appium,若成功启动会输出数行[info]级别的日志,打印出Appium server启动成功后占用的端口。

如果无法显示appium-doctor,可以npm install -g appium安装

UIautomatorviewer使用

Android 4.1发布的,uiautomator是用来做UI测试的。也就是普通的手工测试,点击每个控件元素 看看输出的结果是否符合预期。比如 登陆界面 分别输入正确和错误的用户名密码然后点击登陆按钮看看是否能否登陆以及是否有错误提示等。

找到Andriod sdk安装目录下的uiautomatorviewer.bat,E:\android-sdk-windows\tools\uiautomatorviewer.bat,双击打开

由于自动获得手机信息失败,因此我只能通过手工进行获取

1
2
3
Error obtaining UI hierarchy
Reason:
Error while creating temporary file to save snapshot:null

自动导入成功的结果:

手工获取手机信息

据说Andriod8.0以上就无法使用uiautomator直接连接了,因此需要截图一步步操作

1
2
3
4
5
6
# dump资源文件 再导出到本地
$ adb shell uiautomator dump
$ adb pull /sdcard/window_dump.xml
# 获取截图 导出
$ adb shell screencap -p /data/local/tmp/app.png
$ adb pull /data/local/tmp/app.png .

或者编写bat脚本

1
2
3
4
5
6
7
@echo on

adb shell uiautomator dump /sdcard/app.uix
adb pull /sdcard/app.uix .

adb shell screencap -p /sdcard/app.png
adb pull /sdcard/app.png .

传到Window里,有了截图文件和资源文件,点击UI Automator Viewer菜单栏第一个图标手工导入后即可解析,分析UI

app

  1. 获取快照
    • 当你要分析一个页面时,首先将手机的页面停留在你要分析的页面,然后用数据线连接电脑。
  2. 页面层级
    • 右上方的整个区域,就是当前页面布局的层级关系
  3. 不可用区域
    • 右上方的整个区域中的第二个按钮Toggle NAF Nodes,按下后出现的黄色区域代表,这些控件是不被Uiautomator工具识别,无法获取到这些控件的实例
  4. 属性详情
    • 右下方的整个区域,是当前选中的页面或者是控件的属性信息。写代码的时候就是需要通过查看属性中的控件的id或者是text等来获取控件的实例,然后点击操作它。

编写脚本

  1. 创建项目:创建新的Java项目(注意不是Android项目)。在该项目中来创建测试代码。
  2. 导入库和包:在Project Explorer视图中,右键点击测试项目,选择“ Properties > Java Build Path”,然后选择“Libraries” tab界面。在“Libraries”界面选择“ Add Library > JUnit”来添加JUnit3 库;然后点击“Add External JARs… ”并导航到Android SDK目录。选择platforms目录下面的 uiautomator.jarandroid.jar文件。

uiautomatorviewer

uiautomatorviewer详解、脚本介绍

踩坑记录

报错adb devices: list of devices attached

  1. unauthorized

    设置->更多设置->开发者选项->撤销USB调试授权->重新授权即可

  2. offline

    1
    2
    $ adb kill server
    $ adb start server

▲. AC->Activity coverage、WC->Widget coverage

开发者测试

同样需要配置Java sdk和Andriod SDK环境,除此之外还需要配置maven

配置maven

1.在maven官网下载
apache-maven-3.6.2-bin.zip
后解压,根据视频配置好maven

2.发现最初安装eclipse时没有安装maven,于是安装maven.菜单–>windwos–>install new software–>输入 http://download.eclipse.org/technology/m2e/milestones/1.4后回车

环境配置好后,测试一下

测试结果

  • branchscore是主要评分规则
  • 变异得分无法实时查看,使用选手最后一次的提交脚本统一运行

Junit使用

DEMO坑点记录:

1.JUnit4和JRE1.7配套使用,Junit5需要8以上。而JUnit4和JUnit5都不支持JRE11,所以当时我的报错是The import org.apache cannot be resolved.

2.右键项目->build path -> Config build path -> Libraries后还是报错,java.lang.NoClassDefFoundError: org/junit/runner/manipulation/Filter…解决方法是:①菜单栏->projects->clean②build path -> Config build path -> Libraries->remove重新导入Junit③运行OK

编写规范

1.测试方法上必须使用@Test进行修饰
2.测试方法必须使用public void 进行修饰,不能带任何的参数
3.新建一个源代码目录来存放我们的测试代码
4.测试类的包应该和被测试类保持一致
5.测试单元中的每个方法必须可以独立测试,测试方法间不能有任何的依赖
6.测试类使用Test作为类名的后缀(不是必须)
7.测试方法使用test作为方法名的前缀(不星必须)|

运行流程

1.@BeforeClass修饰的方法会在所有方法被调用前被执行,而且该方法是静态的,所以当测试类被加载后接着就会运行它,而且在内存中它只会存在一份实例,它比较适合加载配置文件
2.@AfterClass所修饰的方法通常用来对资源的清理,如关闭数据库的连接
3.@Before和@After会在每个测试方法即(@Test修饰的方法函数)的前后各执行一次。

@Test:将一个普通的方法修饰成为一个测试方法

  • @Test(expected=XX.class)

    1
    2
    3
    4
    5
    @Test(expected=ArithmeticException.class)
    private void divided() {
    // TODO Auto-generated method stub
    assertEquals(0, new calculate().divide(6, 0));
    }
  • @Test(timeout=毫秒)

@BeforeClass:它会在所有的方法运行前被执行,static修饰
@AfterClass:它会在所有的方法运行结束后被执行,static修饰
@Before:会在每一个测试方法被运行前执行一次
@After:会在每一个测试方法运行后被执行一次
@lgnore:所修饰的测试方法会被测试运行器忽略
@RunWith:可以更改测试运行器org.junit.runner.Runner

测试套件

1.测试套件就是组织测试类一起运行的
写一个作为测试套件的入口类,这个类里不包含其他的方法
更改测试运行器Suite.class
将要测试的类作为数组传入到Suite.SuiteClasses(0)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/** 
* Project Name:softTest
* File Name:SuiteTest.java
* Package Name:com.test.demo
* Date:2019年9月15日下午1:57:13
* Copyright (c) 2019, chenzhou1025@126.com All Rights Reserved.
*
*/
package com.test.demo;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@Suite.SuiteClasses({calculateTest.class})
public class SuiteTest {

}

参数化设置

1.更改默认的测试运行器为RunWith(Parameterized.class)
2.声明变量来存放预期值和结果值
3.声明一个返回值为Collection的公共静态方法,并使用@Parameters进行修饰
4.为测试类声明一个带有参数的公共构造函数,并在其中为之声明变量赋值

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/** 
* Project Name:softTest
* File Name:parameterTest.java
* Package Name:com.test.demo
* Date:2019年9月15日下午2:06:38
* Copyright (c) 2019, chenzhou1025@126.com All Rights Reserved.
*
*/
package com.test.demo;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;


@RunWith(Parameterized.class)
public class parameterTest {
private int expected = 0;
private int input1 = 0;
private int input2 = 0;

@Parameters
// 给构造函数赋值的时候被调用的
public static Collection<Object[]> t() {
return Arrays.asList(new Object[][] {
{3,1,2},
{4,2,2},
});
}

public parameterTest(int expected, int input1, int input2) {
this.expected = expected;
this.input1 = input1;
this.input2 = input2;
}

@Test
public void testAdd() {
assertEquals(expected, new calculate().add(input1, input2));
}
}

注意点:

定位控件的参数选择要求:

  1. 对脚本控件定位参数的选择要追求在要求范围内的唯一性:

    • 参数选择优先级:控件 Resource-id (driver.findElementById())> 控件 XPath(driver.findElementByXPath())

      • id举例:com.floral.life:id/tv_title
      • Xpath举例://android.widget.TextView[@text='鲜切花 '],▲.(此处’鲜切花 '的花字后面还有一个空格,所以不要自己输入属性值,应该直接把在 UI Automator Viewer 中的值直接拷贝到代码中去)。
    • Xpath选择时,首要选择 text、content-desc 这种特殊性较强的属性值,不要选择 index、bounds 这种多个控件极易相同(即未满足全局唯一)的属性值。

    • 脚本中使用 XPath 进行定位时,务必与脚本编写要求中的 XPath 格式完全一致,即//控件类名[@控件属性名='控件属性值']不要使用//*[@控件属性名='控件属性值']等一系列其他格式

  2. 脚本中不要使用 driver.findElementsByxxx()一类的方法,不要用该方法
    定位多个控件得到一个 list 再循环来操作 list 中控件(除非该控件的 XPath都不能满足在测试范围内的全局唯一)。

  3. 脚本中允许自定义函数,但对于 driver.findElementById()这类原生方法,不要进行封装。

  4. 逻辑上是一句话的代码务必写在一行内,不要在函数的参数处换行。

编程建议:

  1. 必须使用断言
    • 确认最后提交的测试用例全部正确, Webide或者客户端能运行得分
    • 使用setup()和teardown()方法进行环境初始化
    • 使用timeout限制测试用例运行时间,避免测试用例出现无响应情况
  2. Evosuite生成的捕获异常的自动测试用例,可能导致变异无法跑通,
    学生自己注意
  3. 测试点注意事项:
  • 对double类型进行判断

    1
    2
    3
    4
    5
    6
    @Test
    public void test(){
    double a = 1.0;
    assertEquals(1.0,a,0.00001) // bingo
    //assertEquals(1.0,a,0.00001) wrong
    }
  • 对控制台输出进行测试

    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
    30
    31
    32
    33
    34
    import static org.junit.Assert.*;

    public class BinPackageTest{
    String sep;
    BinPackage bp;
    PrintStream console=null
    ByteArray InputStream in=null
    ByteArrayOutputStream out=null
    InputStream input=null

    @Before
    public void setUp()throws Exception {
    bp=new BinPackage();
    out=new ByteArrayoutputstream();
    input=System.in;
    console=System.out;
    System.setout(new PrintStream(out));
    sep=System.getProperty("line.separator");
    }

    @After
    public void tearDown()throws Exception {
    System.setIn(input);
    out.close();
    System.setout(console);
    }
    @Test(timeout=4000)
    public void test1(){
    in=new ByteArrayInputStream(("2"+sep+"12"tsep +"3"+sep+"211"+sep+"222"+sep+"232").getBytes());
    System.setIn(in);
    bp.entrance();
    string ans=out.tostring();
    assertEquals("false"+ sep+"true"+sep+"22"+sep+"false"+sep,ans);
    }
  • 对异常报错进行测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    import static org.junit.Assert.*;
    import org.junit.Rule;
    import org.junit.Test;
    import org.junit.rules.ExpectedException;


    public class AccountTest{
    private static final double DOUBLE_DELTA=1e-15;

    @Rule
    public ExpectedException thrown=ExpectedException.none();

    @Test(timeout=4000)
    public void test1(){
    Bank bank=new Bank();
    Account checkingAccount=new Account(Account.CHECKING);
    Customer bill=new Customer("Bi11").openAccount(checkingAccount);
    bank.addCustomer(bil1);
    thrown.expect(I1legalArgumentException.class);
    thrown.expectMessage("amount must be greater than zero");
    checkingAccount.withdraw(-100.e);
    }
    }

Nextday 参数化单元测试(测试用例)设计

附录

更新mooctest插件:mooctest.net_plugin

在官网下载最新的插件mooctest.net_plugin.zip后解压,然后打开eclipse中的Help->Install new software->add->local->选择解压文件夹,安装即可

adb unauthorized

1.使用adb连接手机时,即使打开了usb调试,手机添加了信任,仍然出现unauthorized的提示

2.C:\Users\(Username)\.android里面删掉adbkey和adbkey.pub两个文件(没添加过信任的话是没有的),然后重新插拔手机

执行:

1
2
adb kill-server
adb start-server

△如果上述方式还是无效的话,选择“开发者测试”->"调试"中的撤销USB调试授权,然后重新上述操作

Author: Mrli

Link: https://nymrli.top/2019/09/14/软件测试大赛/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
如何成为一位老司机——考驾照经历
NextPost >
Java自动化构建工具——Maven
CATALOG
  1. 1. 软件测试大赛
    1. 1.1. 初学流程
    2. 1.2. 移动应用测试开发
      1. 1.2.1. 环境配置
        1. 1.2.1.1. 配置Java环境
        2. 1.2.1.2. 安装ADB
        3. 1.2.1.3. 安装Node.js
        4. 1.2.1.4. 安装Appium
      2. 1.2.2. UIautomatorviewer使用
        1. 1.2.2.1. 手工获取手机信息
        2. 1.2.2.2. 编写脚本
        3. 1.2.2.3. 踩坑记录
    3. 1.3. 开发者测试
      1. 1.3.1. 配置maven
      2. 1.3.2. Junit使用
        1. 1.3.2.1. DEMO坑点记录:
        2. 1.3.2.2. 编写规范
        3. 1.3.2.3. 运行流程
        4. 1.3.2.4. 测试套件
        5. 1.3.2.5. 参数化设置
      3. 1.3.3. 注意点:
        1. 1.3.3.1. 定位控件的参数选择要求:
      4. 1.3.4. 编程建议:
      5. 1.3.5. Nextday 参数化单元测试(测试用例)设计
    4. 1.4. 附录
      1. 1.4.1. 更新mooctest插件:mooctest.net_plugin
      2. 1.4.2. adb unauthorized