测试入门篇

测试:

基础概念:

  1. 什么是需求

    • 用户需求: 简单可以理解为甲方的需求,程序员需要完成的用户需求

    • 软件需求: 也就是功能需求,该需求会详细描述开发人员需要实现的功能.

    软件需求是测试人员进行测试的基本依据.

    测试人员根据软件需求文档来设计测试用例

    用户需求不能作为开发和测试的基本依据,因为用户需求不一定合理,需要将用户需求转为软件需求

  2. 什么是测试用例:

    测试人员在执行之前需要编写测试用例.测试用例的好怀与产品的测试质量有很大的关联关系.

    测试用例是实施测试而向测试的系统提供的一组集合,这组集合包括

    1. 测试环境.

    2. 测试步骤.

    3. 测试数据.

    4. 预期结果.

    在这里插入图片描述

    现在测试用例都是使用思维导图的方式来编写

  3. 什么是BUG

    也就是软件错误:当且仅当规格说明是存在的并且正确,程序与规格说明之间的不匹配才是错误。当需求规格说明书没有提到的功能,判断标准以最终用户为准:当程序没有实现其最终用户合理预期的功能要求时,就是软件错误。

    也就是功能不符合软件需求说明书或者需求说明书没有说明.但是功能不符合用户需求功能的就是软件错误也就是BUG.

  4. 开发模型:

    就是开发流程或者项目的推进流程(软件的生命周期)

    1. 需求分析.(需求是否合理)

    2. 计划,(什么时候开始,整个流程多久,什么时候结束)

    3. 设计(将需求细化,进行技术设计(使用什么框架,设计哪些接口,采用什么技术))

    4. 编码(参照需求文档编码)

    5. 测试 (编写测试用例并根据测试用例进行测试)

    6. 运行与维护

    瀑布模型:
    在这里插入图片描述

    线性结构: 意味着前一个阶段结束后下一个阶段才能开始.可能会导致风险在后期的测试阶段才暴露,失去提前纠正的机会.

    螺旋模型:

    在这里插入图片描述

    在瀑布模型的基础上增加了风险分析,测试随着开发的迭代而迭代

    增量模型:

    在这里插入图片描述

    将项目进行模块化,使得每个模块能够进行独立开发与测试.

    迭代模型:

    迭代模型会先完成基础功能的版本,再经历一起一起的迭代优化,慢慢完善.

    敏捷模型:

    不重视开发的流程,重视开发的效率.

    • 敏捷宣言:
    1. 强调团队内部人员尽可能的进行高效的沟通,

    2. 敏捷模型最终的标准就是可交付的软件

    3. 敏捷宣言的特点: 轻流程, 轻文档, 重目标, 重产出

    在这里插入图片描述

    敏捷模型scrum:

    每个迭代周期为1 - 4 周, 一般为一周

    了解三个重要的角色和五个重要会议:

    三个重要角色:

  • 产品经理

  • 项目经理

  • 研发团队

    五个重要会议:

  • 需求发布会议 : 确定本次迭代要实现的需求

  • 迭代计划会议 : 明确需求拆分成一个个任务,明确每个任务对应的责任人.初步评估工时.

  • 每日会议: 研发团员需要回答三个问题: 昨天做了什么,今天要做什么.遇到了什么问题.每日会议结束之后的产物就是可交付的软件

  • 演示会议: 每日会议结束之后的产物: 用户的需求

  • 回顾会议: 回顾之前开发的可取点以及需要改进点

  1. 测试流程.

    1. 需求分析

    2. 测试计划

    3. 测试设计与开发

    4. 执行测试

    5. 测试评估

    测试V模型:

    在这里插入图片描述

    明确测试有不同的类型 而且每个类型与前期开发工作之前的队友关系

    缺陷就是测试后置

    测试W模型:

    在这里插入图片描述

    测试与开发是同步进行的.能够全面,尽快地发现问题.

    开发和测试虽然是同步的,但是仍然存在前后关系.

BUG:

创建一个合理的bug:

创建bug的目标是为了能够让其他人尝试复现.

创建bug的要素:

  1. 问题的版本

  2. 发现问题的环境

  3. 发现问题的步骤

  4. 预期结果

  5. 实际结果

bug 的级别:

  • 崩溃 : 一般是系统崩溃,死机,数据库数据丢失等.

  • 严重 : 主要功能丧失,用户数据丢失,功能设计与需求严重不符等.

  • 一般 : 功能没有完全实现但是不影响使用,查询时间长等.

  • 次要 : 功能已经实现,但是界面或者性能缺陷,一般是建议优化类问题.

bug的什么周期:

在这里插入图片描述

  • new: 新发现的bug.

  • open: 确认是bug,并且认为需要进行修改

  • Rejected: 认为不是bug,拒绝修改

  • delay: 延迟修改.

  • fixed: 立即修改.

  • closed: 认为bug已经修改并且验证成功, bug关闭

  • reopen: 验证失败,需要重新修改.

跟开发争执如何解决:

  1. 查自身,检查bug是否描述不清楚

  2. 对于等级低的bug,要劝说开发站在用户的角度考虑问题

  3. BUG的定级要有理有据.

  4. 不光能提出bug,最好也能提出解决方案.

  5. 组织bug评审: 邀请代表参加(产品代表,开发代表,测试代表等)

    bug评审会议要解决以下问题:

    • 如何修改bug

    • 如何避免类似的问题发生

  6. 对事不对人.

测试用例:

编写测试用例的万能公式:

功能测试+性能测试+界面测试+兼容性测试+易用性测试+安全测试

  • 功能测试: 对产品的功能设计测试用例 (来源是需求文档 / 日常经验)

  • 性能测试: 功能没有问题不代表性能好.所以需要进行性能的测试

  • 界面测试: 大小,颜色,材质,形状等等

  • 兼容性测试: 软件的不同版本是否兼容.不同的系统版本,不同浏览器,数据兼容性等.

  • 易用性测试: 产品是否具备简单易上手的属性,

  • 安全测试: 用户的隐私数据是否加密,SQL注入,越权问题

案例: 登录功能的测试:

设计测试用例的方法:

  • 等价类:

    也就是当我们需要测试的数据特别多时,我们可以将测试数据分为两个等价类: 有效等价类和无效等价类, 有效等价类中是针对需求文档有意义的测试数据,无效等价类是针对需求文档无意义的测试数据,从有效等价类和无效等价类中选出一个测试用例作为代表,如果这个测试用例正确,则认为等价类中的测试用例都正确.

    例如密码的测试: 要求为6 - 18位:

    有效等价类 : 6-18位 (代表 10位)

    无效等价类 : 小于6位 ( 代表 1 位) 大于18位(代表 20 位)

  • 边界值: 依据边界值测试.

    同样以密码的测试为例:

    有效边界: 6 和 18

    无效边界: 5 和 19

  • 判定表(因果图)

    使用场景: 输入条件的组合对应不同的结果

    判定表设计测试用例的步骤:

    1. 确认输入条件和输出条件

    2. 找出输入条件和输出条件之间的关系

    3. 画判定表

    4. 根据判定表编写测试用例

    案例:

    在这里插入图片描述

    判定表:

    在这里插入图片描述

    根据判定表编写测试用例:

    在这里插入图片描述

  • 场景设计法:

    分为基本事件流和备选事件流

    以ATM取钱为例: 先设计基本事件流和备选事件流,再根据事件流编写测试用例.

    在这里插入图片描述

    如何确定边界值:在这里插入图片描述

  • 正交法:

    allpairs

    案例: 测试:

    在这里插入图片描述

    1. 找出因素数和水平数

      在这里插入图片描述

    2. 使用allparis生成正交表

      命令为: allpairs.exe 0109.txt>0109jg.txt

      在这里插入图片描述

    3. 根据正交表编写测试用例:

      在这里插入图片描述

    4. 补充重要的测试用例:

      在这里插入图片描述

    如何使用allparis生成正交表

在这里插入图片描述
在这里插入图片描述

  • 错误猜测法:

    依赖个人经验来编写测试用例.

进阶篇(主要介绍测试方法):

  • 可靠性测试:

    可靠性 = 正常运行时间 / ( 正常运行时间+ 非正常运行时间 )

    可靠性指标一般要达到4个9或者5个9(99.99% 99.999% )

    如何进行可靠性测试:

  • 容错性测试:

    系统能够接受的错误,也就是虽然发生了错误但是不影响使用.

可靠性与容错性的区别:

案例: 有一架飞机,有4个引擎,其中一个引擎坏了,但是飞机能飞行,那么说明这个飞机的可靠性差,但是容错性好.

  • 安装卸载测试:

    测试安装卸载功能.

  • 内存泄漏测试:

    造成内存泄漏的常见原因:

    1. 分配完内存没有回收

    2. 程序的写法有问题,内存没有正常回收

    3. 使用的API函数有问题,造成内存泄漏

    如何测试:

    1. 人工检查: 人工地查找没有回收的内存

    2. 自动工具: 借助测试内存泄漏的工具

  • 弱网测试:

    在网络情况不好的情况下,可能会造成客户端频繁地发送请求.

    如何实施弱网测试: 借助工具模拟弱网环境 (Fiddler)

    1. 打开弱网设置
      在这里插入图片描述

    2. 打开设置弱网的脚本

在这里插入图片描述

  1. 设置上行速率和下行速率

    在这里插入图片描述

    注意英文解释: 单位为多少ms消耗1KB 注意速率的换算.

    速率参考:

    对于B 与 b:
    1B = 8b
    

    在这里插入图片描述

  • 黑盒测试:

    纯功能测试.不关心具体怎么实现,(功能测试)

  • 白盒测试:

    关注程序的内部实现,(单元测试)

  • 灰盒测试:

    介于黑盒和白盒之间. (集成测试)

为什么灰盒测试不能取代黑盒测试和白盒测试:

灰盒测试没有白盒测试详尽,灰盒测试没有黑盒测试覆盖产品的广度大.

  • 冒烟测试:

    测试的第一步,评估软件,系统是否具备可测试的条件.

  • 回归测试;

    对于历史版本,历史功能进行测试,保证功能都是符合要求的. (借助自动化来进行回归测试)

对于自动化测试:

自动化测试是具有局限性的,只是协助测试人员进行测试的工具.

在这里插入图片描述

自动化测试:

自动化测试的分类:

  1. 接口自动化测试

  2. UI自动化测试

  3. 移动端自动化测试

  4. web端自动化测试

selenium( web 自动化测试工具 )

优点:

  1. 开源免费,

  2. 支持多浏览器,(如Chrome,Firefox,IE)

  3. 支持多系统(如Linux,Windows,MacOS)

  4. 支持多语言(如Java,Python)

  5. selenium包提供了很多提供可测试使用的API

环境部署:

Chrome浏览器

Chrome驱动

selenium工具包

什么是驱动:

驱动计算机和设备工作起来.

人工测试的情况下,人手动打开浏览器,那么驱动是人力.

对于自动化来说,代码无法直接打开浏览器,这个时候就需要借助驱动程序来打开浏览器

selenium编写的脚本是如何打开浏览器的:

使用selenium实现web自动化测试实例:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--remote-allow-origins=*");
        ChromeDriver chromeDriver = new ChromeDriver(options);

        Thread.sleep(5000);
        chromeDriver.get("https://www.baidu.com");
        Thread.sleep(5000);
        chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("迪丽热巴");
        Thread.sleep(5000);
        chromeDriver.findElement(By.cssSelector("#su")).click();
        Thread.sleep(5000);
        chromeDriver.quit();
    }
}

注意这里,一开始并没有使用第一二句代码.出现了禁止访问403.,而加上之后就没有403禁止访问的问题了.

在这里插入图片描述

selenium常用方法:

常见元素操作方法:
  1. 查找页面元素:

    findElement()

    参数: By类 ( 提供通过什么方式来查找元素 )

    返回值: List< webElement >

    对于内容则需要遍历打印出来
    
    • By.cssSelector(“id”) 来查找

      当元素在页面能找到,则正常退出

      当元素在页面不能找到,则程序执行 报错

    • By.Xpath:

      语法: 层级:/ 子级 //跳级

      属性: @

      函数: contains()

      通过前端copy xpath就可以了

      但是xpath有时候的定位不唯一,则需要手动修改,

      修改实例:

      在这里插入图片描述

  2. 输入文本 sendKeys()

    在这里插入图片描述

    找到需要输入文本的页面元素,再使用sendKeys() 传输文本

  3. 点击 click()

  4. 提交 submit() 通过回车键提交

    对于submit,selenium官方更推荐使用click来完成提交.

  5. 清除 clear()

  6. 获取文本 getText() 返回值是String

    并不是所有的标签都能获得到文本,例如百度一下的按钮的文本就不能通过getText获得,

    这是因为"百度一下"是按钮的value属性,并不是文本.

    在这里插入图片描述

  7. 获取属性的值 getAttribute()

    示例:

    String bottonText = driver.findElement(By.cssSelector("#su" )).getAttribute( name: "value");
    
    
    
  8. 获取URL getCurrentUrl()

  9. 获取标题 getTitle()

窗口:

窗口大小的设置: 最大化,最小化,全屏窗口,手动设置窗口大小.

示例:

        //最大窗口
        chromeDriver.manage().window().maximize();
        //最小窗口
        chromeDriver.manage().window().minimize();
        //全屏
        chromeDriver.manage().window().fullscreen();
        //自定义窗口大小
        chromeDriver.manage().window().setSize(new Dimension(1024,1024));

获取所有的句柄:

在这里插入图片描述

失败案例讲解:

  1. 为什么我们通过百度首页点击进入百度图片,再输入"迪丽热巴" 百度一下会失败?

    这是因为我们驱动的句柄并没有发生转换,驱动依然停留在百度首页,所以我们需要转换句柄.

  2. 为什么通过百度首页搜索"迪丽热巴"再点击搜索,查找网页元素会显示报错: “没有这个元素”

            chromeDriver.get("https://www.baidu.com");
            chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("迪丽热巴");
            chromeDriver.findElement(By.cssSelector("#su")).click();
            chromeDriver.findElement(By.cssSelector("#\\31  > div > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > div.title-wrapper_XLSiK > a > div > p > span > span")).click();
            chromeDriver.quit();
    

    这是因为页面渲染的速度远远不如代码执行的速度.所以代码查找这个元素的时候页面还没有渲染成功,所以失效.

    解决方法: 当程序执行的时候我们需要在代码里添加等待机制.

等待:
  • 强制等待 : 程序阻塞等待

    Thread.sleep()
    
  • 隐式等待 :

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(秒数));
    
    //隐式等待
            chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
            chromeDriver.get("https://www.baidu.com");
            chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("迪丽热巴");
            chromeDriver.findElement(By.cssSelector("#su")).click();
            chromeDriver.findElement(By.cssSelector("#\\31  > div > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > div.title-wrapper_XLSiK > a > div > p > span > span")).click();
            chromeDriver.quit();
    

    隐式等待会作用于driver的整个生命周期 , 隐式等待会一直轮询判断元素是否存在,如果不存在就等待设置好的时间里不断的进行轮询,直到元素能够被找到

  • 显式等待 :

    与隐式等待不同, 这个只轮询等待这一条语句

    new WebDriverWait(driver,Duration.ofSeconds(5)).until(driver->driver.findElement(By.cssSelector("#kw")));
    
      new WebDriverWait(chromeDriver,Duration.ofSeconds(5)).until(driver->driver.findElement(By.cssSelector("#\\\\31  > div > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > div.title-wrapper_XLSiK > a > div > p > span > span")));
    
浏览器操作:

回退前进刷新操作:

        //浏览器操作:
        //后退
        chromeDriver.navigate().back();
        //前进
        chromeDriver.navigate().forward();
        //刷新
        chromeDriver.navigate().refresh();
弹窗:

弹窗类型:

在这里插入图片描述

切换弹窗: (创建弹窗对象)

Alert alert = driver.switchTo().alert();

确认:

alert.accept();

取消:

alert.dismiss();

输入文本:

alert.sendkeys();

虽然警告弹窗只有确认按钮, 注意 accept 和 dismiss 都能够处理

虽然警告弹窗和确认弹窗都没有输入文本的地方,但是如果要执行alert.sendkeys() , 代码也不会报错, 只是没有效果.

选择框:

选项的选择方式:

  1. 创建选择框对象:

    Select select = new Select(new WebElement);
    
  2. 根据文本选择

    select.selectByVisibleText(文本内容);
    
  3. 根据属性值选择

    select.selectByValue(属性值);
    
  4. 根据序号选择

    select.selectByIndex(序号);
    
执行脚本:

执行js代码:

driver.executeScript(脚本代码);
文件的上传:
driver.findElenment(By.cssSector(元素)).sendkeys("文件路径 + 文件")
浏览器的参数设置

在实际的工作中,测试人员将自动化部署在机器上自动执行,并不会查看自动化执行的过程,而是查看自动化执行的结果.

        ChromeOptions options = new ChromeOptions();
        //参数 
        //无头模式
         options.addArguments("-headless");
 无头模式是指一种特殊的浏览器模式,这种模式下,浏览器并没有提供可视化用户界面(GUI)。这意味着当浏览器处于无头模式时,它不显示任何图形界面元素,如菜单、工具栏或浏览器窗口。无头模式特别适合于需要自动化访问网页或在服务器端执行的任务,如网络爬虫、数据抓取、自动化测试以及网页截图等。

Junit

junit是java的单元测试工具

注解:
  • @ Test

    表示这个方法是测试方法, 执行当前这个类,会自动执行该类的所有@ Test 注解的方法

  • @ BeforeEach

    当前的方法需要在每个用例之前都要执行一次

  • @ BeforeAll

    当前的方法需要在用例之前执行一次

    被修饰的方法必须为静态方法

  • @ AfterEach

    当前的方法需要在每个用例之后都要执行一次

  • @ AfterAll

    当前的方法需要在用例之后执行一次

    被修饰的方法必须为静态方法

断言:

Assertions

  • assertEquals(期望值,实际值) 判断期望值与实际值是否相等

  • assertNotEquals(期望值,实际值) 判断期望值与实际值是否不相等

  • assertTrue(条件) 判断条件是否为true

  • assertFalse(条件) 判断条件是否为false

  • assertNull(值) 判断值是否为空

  • assertNotNull(值) 判断值是否不为空

用例的执行顺序:

手动控制用例的执行顺序

@ TestMethodOrder()

示例:

import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JunitTest {

    @Test
    @Order(1)
    void loginTest() {
        System.out.println("login");

    }
    @Test
    @Order(2)
    void editTest() {
        System.out.println("edit");
    }
    @Test
    @Order(3)
    void AindexTest() {
        System.out.println("Aindex");
    }
}
参数化:

@ ParameterizedTest

单参数示例 :

 @ValueSource(strings = {"lucy","mary","haitaos"})
    void SparamsTest(String name){
        System.out.println(name);
    }

多参数示例 :

@CsvSource({"mary,20,女","lucy,25,女","bob,50,男","bob,50,男","bob,50,男","bob,50,男","bob,50,男","bob,50,男","bob,50,男","bob,50,男","bob,50,男","bob,50,男","bob,50,男","bob,50,男","bob,50,男"})
    void muchParamsTest(String name,int age,String sex){
        System.out.println("name:"+name+",age:"+age+",性别:"+sex);
    }

使用Excel文件示例:

 @ParameterizedTest
    @CsvFileSource(files = "D:\\file\\other\\mycsv.csv")
    void csvfileParamsTest(String name , int age){
        System.out.println("name:"+name+",age:"+age);
    }
 //不使用系统自带的EXCEL文件就会报乱码的错误
    @CsvFileSource(files = "D:\\file\\other\\aaaa.csv")
    void csvWrongTest(String name,int age){
        System.out.println("name:"+name+",age:"+age);
    }

动态方法:

   //通过动态方法来提供数据源
    @MethodSource
    void dynamicmethodPramsTest(String name,int age){
        System.out.println("name:"+name+",age:"+age);
    }
    static Stream<Arguments> dynamicmethodPramsTest() throws InterruptedException {
        //构造动态参数
        String[] arr = new String[5];
        for (int i = 0; i< arr.length;i++){
            Thread.sleep(500);
            arr[i] = System.currentTimeMillis()+"";
        }
        return Stream.of(
                Arguments.arguments(arr[0],20),
                Arguments.arguments(arr[1],20),
                Arguments.arguments(arr[2],20),
                Arguments.arguments(arr[3],20),
                Arguments.arguments(arr[4],20)
        );
    }
测试套件

创建一个类 ,通过@ Suite 标识该类为特殊套件类,不是测试类

  1. 指定类来运行

    类下想要运行的用例需要被@Test注解

    @Suite
    @SelectClasses({aaaTest.class,bbbTests.class})
    public class runSuite {
    }
    
  2. 指定包来运行

    对于使用包名来指定的运行范围,那么该包下的所有的测试类的命名需要以Test/Tests结尾

    @Suite
    @SelectPackages("com.autoTest0212“)
    public class runSuite {
    }
    

throws InterruptedException {
//构造动态参数
String[] arr = new String[5];
for (int i = 0; i< arr.length;i++){
Thread.sleep(500);
arr[i] = System.currentTimeMillis()+“”;
}
return Stream.of(
Arguments.arguments(arr[0],20),
Arguments.arguments(arr[1],20),
Arguments.arguments(arr[2],20),
Arguments.arguments(arr[3],20),
Arguments.arguments(arr[4],20)
);
}


#### 测试套件

创建一个类 ,通过@ Suite 标识该类为特殊套件类,不是测试类

1. 指定类来运行
   
   类下想要运行的用例需要被@Test注解
   
   ```java
   @Suite
   @SelectClasses({aaaTest.class,bbbTests.class})
   public class runSuite {
   }
  1. 指定包来运行

    对于使用包名来指定的运行范围,那么该包下的所有的测试类的命名需要以Test/Tests结尾

    @Suite
    @SelectPackages("com.autoTest0212“)
    public class runSuite {
    }
    

本章总结了测试方法,BUG,测试用例编写,selenium自动化测试.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小连~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值