精华内容
下载资源
问答
  • 业务逻辑单元自动化测试 package com.lujiatao.springboot.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBoo...

     

    源码附件:https://gitee.com/steffens/httpinterface/tree/master/bookcode38382

     

    业务逻辑层单元自动化测试

    package com.lujiatao.springboot.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.RequestBuilder;
    import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
    import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.Test;
    
    import com.lujiatao.springboot.Application;
    
    @SpringBootTest(classes = { Application.class })
    public class CalculatorForPpiControllerTest extends AbstractTestNGSpringContextTests {
    	@Autowired
    	private CalculatorForPpiController controller;
    	private MockMvc mock;
    	private RequestBuilder request;
    	private String width;
    	private String height;
    	private String size;
    
    	@BeforeClass
    	public void init() {
    		mock = MockMvcBuilders.standaloneSetup(controller).build();
    		width = "750";
    		height = "1334";
    		size = "4.7";
    	}
    
    	@Test
    	public void testCase1() {
    		sendRequest(width, height, size, "326");
    	}
    
    	@Test
    	public void testCase2() {
    		sendRequest("-1", height, size, "-1");
    	}
    
    	@Test
    	public void testCase3() {
    		sendRequest("0", height, size, "-1");
    	}
    
    	@Test
    	public void testCase4() {
    		sendRequest(width, "-1", size, "-1");
    	}
    
    	@Test
    	public void testCase5() {
    		sendRequest(width, "0", size, "-1");
    	}
    
    	@Test
    	public void testCase6() {
    		sendRequest(width, height, "-1", "-1");
    	}
    
    	@Test
    	public void testCase7() {
    		sendRequest(width, height, "0", "-1");
    	}
    
    	private void sendRequest(String width, String height, String size, String expected) {
    		request = MockMvcRequestBuilders.post("/calculate").param("width", width).param("height", height).param("size",
    				size);
    		try {
    			mock.perform(request).andExpect(MockMvcResultMatchers.jsonPath("PPI").value(expected));
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    }

     

     

    控制器层单元自动化测试

    package com.lujiatao.springboot.service;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
    import org.testng.Assert;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.Test;
    
    import com.lujiatao.springboot.Application;
    
    @SpringBootTest(classes = { Application.class })
    public class CalculatorForPpiServiceTest extends AbstractTestNGSpringContextTests {
    	@Autowired
    	private CalculatorForPpiService service;
    	private int height;
    	private int width;
    	private double size;
    
    	@BeforeClass
    	public void init() {
    		height = 750;
    		width = 1334;
    		size = 4.7;
    	}
    
    	@Test
    	public void testCase1() {
    		Assert.assertEquals(326, service.calculate(width, height, size));
    	}
    
    	@Test
    	public void testCase2() {
    		Assert.assertEquals(-1, service.calculate(-1, height, size));
    	}
    
    	@Test
    	public void testCase3() {
    		Assert.assertEquals(-1, service.calculate(0, height, size));
    	}
    
    	@Test
    	public void testCase4() {
    		Assert.assertEquals(-1, service.calculate(width, -1, size));
    	}
    
    	@Test
    	public void testCase5() {
    		Assert.assertEquals(-1, service.calculate(width, 0, size));
    	}
    
    	@Test
    	public void testCase6() {
    		Assert.assertEquals(-1, service.calculate(width, height, -1));
    	}
    
    	@Test
    	public void testCase7() {
    		Assert.assertEquals(-1, service.calculate(width, height, 0));
    	}
    
    }
    

     

     

    业务逻辑层单元自动化测试-TestNG.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="Suite">
    	<test thread-count="5" name="Test">
    		<classes>
    			<class
    				name="com.lujiatao.springboot.service.CalculatorForPpiServiceTest" />
    		</classes>
    	</test> <!-- Test -->
    </suite> <!-- Suite -->
    

     

     

     

     控制器层单元自动化测试-TestNG.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="Suite">
    	<test thread-count="5" name="Test">
    		<classes>
    			<class
    				name="com.lujiatao.springboot.controller.CalculatorForPpiControllerTest" />
    		</classes>
    	</test> <!-- Test -->
    </suite> <!-- Suite -->
    

     

     

     

    展开全文
  • 安卓自动化业务层测试接口 阅读前需知的基本知识: 1. uiautomator 脚本的执行通过shell命令调起执行,向执行的方法传递参数也是通过shell命令 2 调起的执行方法所在类必须要继承UIATestCasel类 3. 调起方法...

     

     

    安卓自动化业务层测试接口

    阅读前需知的基本知识:

            1. uiautomator 脚本的执行通过shell命令调起执行,向执行的方法传递参数也是通过shell命令

            2  调起的执行方法所在类必须要继承UIATestCasel类

            3.  调起方法内部,职能通过bundle获取外部传递的参数,而不是通过函数参数的方式传递

     

    抛出问题:

           在新的自动化测试框架中,业务层属于API层级,非继承于UIATestCasel类(com.android.uiautomator.testrunner.UiAutomatorTestCase)

           1. 业务API不支持外部通过命令或其他方式执行进行业务API,进行测试;如果每次都构造Case来进行业务API的测试,严重影响业务API的测试开发效率

           2. uiautomator执行只支持通过shell,通过bundle传递参数和获取参数;不支持业务API的直接传参方式

           3. shell执行uiautomator,传递参数只能传递字符串;而业务API的参数是多变的,包括int boolean string String[]等

       

    解决方案:

           1. 针对第一个问题,业务API外部无法直接调起问题;使用java反射机制实现业务API的外部调起:

               新建一个统一的业务API访问类Agent,继承UIATestCasel类,使其可以通过外部shell命令调起

               在外部通过命令传递object和method这两个参数到bundle,在Agent类entry方法中获取bundle并解析出要测试的API的类路径和方法名

               根据类路径和方法名,通过反射在本地调用

          

          2.  针对uiautomator执行,传递参数只能传递字符串,不满足业务API的参数个数和类型不定问题;采用添加中间层,处理后传递到业务层API

               首先根据业务API方法,获取其参数类型列表

               根据每个参数的类型和参数的序号({index}),把bundle中‘p{index}’对应的value的值转化成对应类型

                把转化后的所有参数放到一个对象里,然后通过反射加载到业务API

                Demo: adb shell uiautomator runtest IQiyiAppAutomatedTest.jar -c com.qiyi.library.base.Agent#entry -e object ReaderBusiness -e method runtest0 -e p0 [0,1,3] -e p1 [rer,re,re]

     

           3.  bundle中的值通过shell命令传递,shell命令中有些字符使用,通过自建转义字符列表的方式来解决

                bundle在使用前,进行一次预处理,把当中的自定义转义字符替换掉;现在有的转义字符见下表

    字符对应的转义字符
    空格 {{SPACE}}
    空字符 {{EMPTY}}
    单引号 {{SINGLEQUOTES}}
    双引号 {{DOUBLEQUOTES}}
    左括号 {{LEFTPARENTHESIS}}
    右括号 {{RIGHTPARENTHESIS}}

                 

                 Demo: adb shell uiautomator runtest IQiyiAppAutomatedTest.jar -c com.qiyi.library.base.Agent#entry -e object ReaderBusiness -e method runtest1 -e p0 {{LEFTPARENTHESIS}}who{{LEFTPARENTHESIS}}

     

     CODE LINK: http://files.cnblogs.com/files/udld/Agent_Uiautomator.rar

     

              

    转载于:https://www.cnblogs.com/udld/p/6062322.html

    展开全文
  • 业务层该层主要是App的各种业务操作,比如登录,遍历tab,下单等,也就是说把app中各项业务的操作都封装在业务层。比如说登录操作,我们把它封装一个类,大致的流程是:首先是不是要找到登录入口(可能一个app有很多...

    业务层

    该层主要是App的各种业务操作,比如登录,遍历tab,下单等,也就是说把app中各项业务的操作都封装在业务层。比如说登录操作,我们把它封装一个类,登录的大致的流程是:首先是不是要找到登录入口(可能一个app有很多的入口),然后进入登录界面,输入用户名和密码,再点击登录按钮,这样一个完整的登录业务就算完成了。

    可能你问我为什么要这么做呢?在测试脚本中直接写不就可以了,为什么要把它们分离出来?其实这样做的目的是为了最大程度让测试用例维护性降低。如果以后需求发生变化,比如登陆的逻辑中增加了验证码等,这时只用改业务层中的登录类就可以了,而用例层中的测试脚本并不用改。

    这里写图片描述

    以下为登录业务的代码:
    
    package com.dji.action;
    
    import java.util.concurrent.TimeUnit;
    import com.dji.object.BasePage;
    import io.appium.java_client.AppiumDriver;
    
    /**
     * 登录action
     * @author charlie.chen
     *
     */
    
    public class Login  {
    
         private AppiumDriver<?> driver;
    
         private BasePage loginPage=null;
    
        public Login(AppiumDriver<?> driver) {
            this.driver = driver;
        }
    
    
        //通过登录按钮登录
        public void loginByButton(String userName,String pwd) throws Exception{
            new BasePage(driver,"menuPage").click("我");
            isLogined();
            new BasePage(driver,"minePageNo").click("登录");
            login(userName,pwd);
        }
    
    
        //通过DJI Store登录
        public void loginByStore(String email,String pwd) throws Exception{
            isLogined();
            new BasePage(driver,"minePageNo").click("DJI商城");
            login(email,pwd);
        }
    
    
        // 通过DJI Academy登录
        public void loginByAcademy(String email,String pwd) throws Exception{
            isLogined();
            new BasePage(driver,"minePageNo").click("DJI论坛");
            login(email,pwd);
        }
    
    
        //判断是否已登录,如果已登录就先退出登录
        public void isLogined() throws Exception{
            BasePage minePage=new BasePage(driver,"minePage");
            boolean flag=minePage.isElementDisplayed("用户图像");
            if(flag){
                minePage.swipeToUp();
                driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
                minePage.click("设置");
                loginOut();
            }
        }
    
        //登录操作
        public  void login(String userName,String pwd) throws Exception {   
            loginPage=new BasePage(driver,"loginPage");
            loginPage.type("登录输入账号框", userName);
            loginPage.type("登录输入密码框", pwd);
            loginPage.click("登录");  
            driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        }
    
        //退出登录
        public void loginOut() throws Exception{
            BasePage settingPage=new BasePage(driver,"settingPage");
            settingPage.click("退出DJI账号");
            settingPage.click("确定");
        }
    }
    

    用例层

    该层是实际的测试脚本,也就是调用业务层中的各项业务操作,然后增加验证,判定结果是否正确。

    以下为登录用例:

    package com.dji.cases;
    
    import java.util.concurrent.TimeUnit;
    
    import org.testng.annotations.AfterClass;
    import org.testng.annotations.AfterMethod;
    import org.testng.annotations.AfterTest;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.BeforeMethod;
    import org.testng.annotations.BeforeTest;
    import org.testng.annotations.Listeners;
    import org.testng.annotations.Parameters;
    import org.testng.annotations.Test;
    
    import static org.assertj.core.api.Java6Assertions.*;
    
    import com.dji.action.Login;
    import com.dji.object.BasePage;
    import com.dji.utils.DriverFactory;
    import com.dji.utils.TestNGListener;
    
    import io.appium.java_client.android.AndroidDriver;
    
    @Listeners({ TestNGListener.class })
    public class LoginTest {
    
        private AndroidDriver<?> ad = null;
        private Login login = null;
    
        @Parameters({ "userName", "pwd" })
        @Test(description = "通过登录按钮登录")
        public void loginByButton(String userName, String pwd) throws Exception {
    
            login.loginByButton(userName, pwd);
            ad.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
            // 断言验证用户名是否正确
            //Assert.assertEquals(new BasePage(ad, "minePage").findElement("用户名").getText(), "charlie.chen");   //testNG自带的断言机制
            //采用AssertJ断言机制
            assertThat(new BasePage(ad, "minePage").findElement("用户名").getText()).isEqualTo("charlie.chen");
        }
    
        @Parameters({ "userName", "pwd" })
        @Test(description = "通过DJI Store登录")
        public void loginByStore(String userName, String pwd) throws Exception {
    
            login.loginByStore(userName, pwd);
            ad.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        }
    
        @Parameters({ "userName", "pwd" })
        @Test(description = "通过DJI论坛登录")
        public void loginByAcademy(String userName, String pwd) throws Exception {
    
            login.loginByAcademy(userName, pwd);
            ad.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        }
    
        @Parameters({ "userName", "pwd" })
        @Test(description = "通过飞行记录登录")
        public void loginByFly(String userName, String pwd) throws Exception {
    
        }
    
        // /*
        // * 通过Skypixel关注登录
        // */
        // @Test
        // public void loginByAttention() throws Exception {
        // }
        //
        // /*
        // * 通过Skypixel点赞登录
        // */
        // @Test
        // public void loginByPraise() throws Exception {
        // }
        //
        // /*
        // * 通过Skypixel收藏登录
        // */
        // @Test
        // public void loginByCollect() throws Exception {
        // }
        //
        // /*
        // * 通过Skypixel评论登录
        // */
        // @Test
        // public void loginByComment() throws Exception {
        // }
    
        @BeforeMethod
        public void beforeMethod() throws Exception {
            login = new Login(ad);
            TestNGListener.setDriver(ad);
        }
    
        @AfterMethod
        public void afterMethod() throws Exception {
    
        }
    
        @BeforeClass
        public void beforeClass() {
    
            ad = DriverFactory.createAndroidDriver("PBV0216615001449", "4723", "dji.pilot", "dji.pilot.main.activity.DJIAoaActivity"); 
            ad.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        }
    
        @AfterClass
        public void afterClass() {
            // ad.closeApp();
    
        }
    
        @BeforeTest()
        public void beforeTest() throws Exception {
        }
    
        @AfterTest
        public void afterTest() {
        }
    }
    

    testng.xml文件:

    <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
    <suite name="appiumPRO" parallel="false" preserve-order="true">
    
        <parameter name="port" value="4723" />
        <parameter name="udid" value="PBV0216615001449" />
        <parameter name="appPackage" value="dji.pilot" />
        <parameter name="appActivity" value="dji.pilot.main.activity.DJIAoaActivity" />
    
        <parameter name="userName" value="charlie.chen@dji.com" />
        <parameter name="pwd" value="1weefdsew" />
    
        <test name="LoginTest" preserve-order="true">
            <classes>
                <class name="com.dji.cases.LoginTest" >
                    <methods>
                        <include name="loginByButton" />
                        <include name="loginByStore" />
                        <exclude name="loginByAcademy" />
                        <exclude name="loginByFly" />
    
                        <exclude name="loginByAttention" />
                        <exclude name="loginByPraise" />
                        <exclude name="loginByCollect" />
                        <exclude name="loginByComment" />
                    </methods>
                </class>
            </classes>
        </test>
    
    </suite>
    
    展开全文
  • 自动化测试

    2019-04-01 13:07:24
    自动化测试 软件测试的自动化,在预设条件下运行应用程序或系统,评估结果。预设条件包括正常和异常 自动化框架 一般分为两个层次 上层:管理整个自动化测试的开发、执行和维护。管理整个自动测试,包括自动化测试...

    自动化测试

    软件测试的自动化,在预设条件下运行应用程序或系统,评估结果。预设条件包括正常和异常

    自动化框架

    一般分为两个层次
    上层:管理整个自动化测试的开发、执行和维护。管理整个自动测试,包括自动化测试用例执行的次序、测试脚本的维护、以及集中管理测试用例、测试报告和测试任务等
    下层:主要是测试脚本的开发,充分的使用相关的测试工具,构建测试驱动,并完成测试业务逻辑

    自动化测试的演变:测试工具—-数据驱动—-关键字驱动—-测试框架—-测试平台

    自动化测试方法

    测试对象:UI、接口、代码
    测试过程:系统测试、集成测试、单元测试
    执行人员:测试人员、开发人员

    自动化测试可以在整个测试过程中任何一个阶段实施
    测试人员一般在系统测试时进行自动化测试
    集成测试阶段多进行自动构建、部署,以及冒烟测试的自动化

    自动化测试的优势

    降低大型系统的由于变更或者多期开发引起的大量的回归测试的人力投入,这可能是自动化测试最主要的任务,特别是在程序修改比较频繁时,效果是非常明显的,自动化测试前期人力投入较多,但后期进入维护期后,可节省大量人力,而手工测试后期需要增加大量人力用于回归测试
    减少重复测试的时间,实现快速回归测试
    创建优良可靠的测试过程,减少人为错误
    可以运行更多更繁琐的测试
    可以执行一些手工测试困难或不可能进行的测试
    更好的利用资源
    测试具有一致性和重复性
    测试脚本的重用性

    展开全文
  • 自动化测试笔记 Day01

    2020-09-13 21:49:26
    自动化测试分为:UI ,Service ,Unit 。 即:用户界面业务逻辑,数据处理。 即:UI 自动化测试、JS 自动化测试,接口自动化测试,单元测试及代码审查。 UI 自动化测试工具(交互界面):UFT(QTP),...
  • 大家都知道,一个设计良好的自动化测试框架,就需要考虑到如下几点: 1. 易扩展性 既能满足现在的业务功能需求,又能在日后的项目中复用该框架; 2. 易维护性 当数据,页面设计或业务逻辑发生变更时,能够做稍微...
  • UI自动化测试

    2018-04-08 15:19:22
    分层自动化测试倡导的是,将系统分层,不同层次选用合适的自动化方法进行测试的一种测试策略。某个项目是否都能用自动化覆盖,要看测试负责人的分层策略是否合理、全面。 测试金字塔,依次为UI测试、集成服务...
  • 传统测试认为功能测试(黑盒测试)就是数据驱动测试,而在自动化测试体系中,数据驱动测试则有了新的诠释。以一个基础的自动化框架为例,它可以分为三层设计,数据层、逻辑层、业务层,假设数据层的...
  • app自动化测试方案

    2018-11-28 14:17:58
    单元自动化测试(数据处理):指对软件中最小的可测试单元进行检查和验证,一般需要借助单元测试框架,如java的Junit、TestNG,python的unittest,常见的手段是code review等; 接口自动化测试业务逻...
  • 大家好,本系列教程主要介绍基于Appium的UI自动化测试框架的设计和实践。我将平时的学习和工作的实践一一的总结下来,给初学者一点灵感和启发,如有不对的地方还请大家指出。 所谓UI自动化,顾名思义,主要是...
  • 自动化测试框架需求

    2017-01-12 10:53:46
    先来看看自动化测试框架的架构包括:脚本层(业务组件开发),业务层(流程的开发和组织),数据层相分离,是本次框架组织总的方针,为开展功能自动化测试提供一个高效、稳定、容易的测试实现。 那么为什么要搭建用...
  • 软件自动化测试框架

    2016-07-16 10:49:57
    自动化测试框架一般可以分为上下两个层次,上层是管理整个自动化测试的开发,执行以及维护,在比较庞大的项目中,它体现重要的作用,它可以管理整个自动测试,包括自动化测试用例执行的次序、测试脚本的维护、以及...
  • web-自动化测试流程

    2020-09-25 13:47:26
    1. 自动化测试流程 (1) 需求分析 (2) 挑选适合做自动化测试的功能 (3) 设计测试用例 (4) 搭建自动化测试环境 [可选] (5) 设计自动化测试项目的架构 [可选] (6) 编写代码 (7) 执行测试用例 (8) 生成测试报告并分析...
  • 第二:通用自动化测试工具 第三:组件抽取(组件化): 基础公共组件库 业务模块公共组件 业务模块组件库 第四业务逻辑 第五:测试数据 2 自动化测试脚本质量要求 稳定性:失败重试、...
  • 自动化系统设计 1 分层的目的 1)用户在在玩ui元素与行为操作,各个page之间相互不干扰,需要分离 2)新增用例的时候,每个用例设计都需要考虑配置信息、页面元素信息、行为操作、具体流程设计。不同用例之间的配置...
  • 尽管JUnit一直在与开发人员一起帮助他们进行自动化的单元测试,但随着时间的推移和测试的发展,当自动化测试不断增长时,已经开发了许多基于Java的开源框架,并且JUnit在验证和业务逻辑方面。 在这里,我将讨论2019...
  • 就目前个人观察到的情况,一些负责基础性组件测试的团队,比如底层平台、SDK等,或者是负责功能通用性高的产品,比如防火墙、邮件系统等,都可以做到比较高的自动化率,而且自动化测试开发的过程通常也没有那么纠结...
  • 为了展现关键字自动化测试框架的特点,利用对象的层次关系的特点,设计成关键字,这种关键字的缺陷就在于数据表格中的数据要求不仅仅对业务要熟悉,还要对技术有所了解,所以技术技巧大于实际应用价值。 一.数据...
  • Page Object 是 Selenium 自动化测试项目开发实践的最佳设计模式之一,Page Object 的主要体现于对界面交互细节的封装,这样可以使测试案例更关注与业务而非界面细节,提高测试案例的可读性。认识 Paget Object一、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 406
精华内容 162
关键字:

自动化测试业务层