软件测试

Junit

  • TestCase:一个TestCase表示一个测试
  • TestSuite:一个TestSuite包含一组TestCase,表示一组测试
  • TestFixture:一个TestFixture表示一个测试环境
  • TestResult: 用于收集测试结果
  • TestRunner:用于运行测试
  • TestListener: 用于监听测试过程,收集测试数据
  • Assert:用于断言测试结果是否正确

import static org.junit.Assert.*

使用Assert断言

  • 断言相等: assertEquals(100,x)
  • 断言数组相等: assertArrayEquals({1,2,3},X)
  • 浮点数断言相等: assertEquals(3.1416,x,0.0001)
  • 断言为null: assertNull(x)
  • 断言为true/false: assertTrue(x > 0) assertFalse(x < 0)
  • 其他: assertNotEquals/assertNotNull

使用Before和After

同一个单元测试内的多个测试方法:

  • 测试前需要初始化某些对象 : 在@Before方法中初始化测试资源
  • 测试后可能需要清理资源 fileInputStream.close();:在@After方法中释放资源

异常测试

对可能抛出的异常进行测试:

  • 异常本身是方法签名的一部分
    public static int parselnt(String s) throws NumberFormatException
  • 测试错误的输入是否导致特定的异常
    Integer.parselnt(null)
    Integer.parselnt(“”)
    Integer.parselnt(“xyz”)

使用expected测试异常

注解:

@Test(expected = NumberFormatException.class)

对某个测试案例测试的结果进行分析测试通用模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.Junit;

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner1 {
public static void main(String[] args) {

// 创建一个Result对象,用于存储测试结果
Result result = JUnitCore.runClasses(TestJunit1.class);

// 遍历测试结果中的失败信息
for (Failure failure : result.getFailures()) {
// 打印每个失败信息的字符串表示
System.out.println(failure.toString());
}

// 打印测试是否成功的结果
System.out.println(result.wasSuccessful());
}
}

Web测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;


public class TestEdge {
public static ChromeDriver chromeDriver;

public static void main(String[] args) {
opeanEdge();
}

public static void opeanEdge() {
System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");
chromeDriver = new ChromeDriver();
chromeDriver.get("https://baidu.com/");

}
}

基本元素定位

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
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;


public class TestEdge {
public static ChromeDriver chromeDriver;

public static void main(String[] args) {
opeanEdge();
//id
chromeDriver.findElement(By.id("kw")).sendKeys("软件测试");
//name
chromeDriver.findElement(By.name("wd")).sendKeys("软件测试");
//tagName
chromeDriver.findElementByTagName("input");
//className
chromeDriver.findElement(By.className("soutu-btn")).sendKeys("软件测试");
//linkText
chromeDriver.findElement(By.linkText("图片")).click();
//partialLinkText
chromeDriver.findElementByPartialLinkText("丰收里的中国色").click();
}

public static void opeanEdge() {
System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");
chromeDriver = new ChromeDriver();
chromeDriver.get("https://baidu.com/");

}
}

元素定位cssSelect

  • 根据tagName

    1
    By.cssSelector("input");
  • 根据ID

    1
    2
    By.cssSelect("input#id");
    By.cssSelect("#id");
  • 根据className

    1
    2
    By.cssSelector(".className");
    By.cssSelector("input.className");
  • 精确定位 css

    • 根据元素属性,属性名=属性值,id,class,等都可以写成这种形式

      1
      By.cssSelector("标签名[属性名='属性值']");
    • 多属性

      1
      By.cssSelector("标签名[属性1='属性值'][属性2='属性值']");

元素定位 Xpath

xpath是一个path,一个描述页面元素位置信息的路径,相当于元素的坐标

xpath基于XML文档树状结构,是XML路径语言,用来查询xml文档中的节点

  • 绝对定位:从跟开始找

  • 相对路径:

    例:*[@name=‘phone’]

    • // 匹配指定节点,不考虑他们的位置
    • * 通配符:匹配任意元素节点
    • @ 选取属性
    • [] 属性判断条件表达式

元素操作API

  • click():触发点击
  • clear():清空内容
  • sendKeys:往文本框中写入内容
  • getTagName():获取元素的标签名
  • getAttribute(属性名):根据属性名获取元素属性值
  • isDisplayed():查看元素是否显示

WebDriver相关API

  • get(String url):访问指定URL

  • getCurrentUrl():获取当前页面的URL地址

  • getPageSource():源代码

  • getTitle():获取当前页面的标题

  • quit():关闭驱动对象以及所有相关的窗口

  • close():关闭当前窗口

  • getWindowsHandle():返回当前页面句柄

  • getWindowsHandles():返回所有由驱动对象打开页面所有的句柄,页面不同,句柄不一样

  • manage():获取Options—浏览器菜单操作对象

  • navigate对象:导航–>对浏览器的刷新、回退等操作

    1
    2
    3
    4
    5
    6
    WebDriver.Navigation navigate = chromeDriver.navigate();
    navigate.to("https://czlifetime.eu.org/");
    sleep(5000);
    navigate.refresh();
    sleep(5000);
    navigate.back();

元素三大等待

硬性等待

  • 线程休眠,强制等待

    Thread.sleep(long millis);

隐式等待

藏起来的等待,一次设置,始终有效,针对WebDriver对象,进行的等待时长的设置

作用:对WebDriver对象设置全局等待,每一次操作如遇到页面加载,则默认进入隐式等待,如遇元素无法找到,则进入隐式等待,当达到最大时长时,则继续进行后续的代码

1
2
driver.webdriver.Chrome();
driver.implicity_wait(10);
  • 在设置的超过时间范围内不断查找元素,直到找到元素或者超时

    driver.manage.timeouts().implicityWait(long time,TimeUnit unit);

    • 优点:相对灵活
    • 设置是针对全局的,在WebDriver实例整个生命周期有效,但并不是所有的元素都需要等待
    • 在opeanChrome()方法之前

显示等待

专门用于等待指定的元素对象

1
2
3
4
5
6
7
# 导入显示等待
from selenium.webdriver.support.wait import WebDriverWait

# 针对webdriver对象,最大等待10秒,每0.5秒一次频率检索指定元素
# until指定元素,返回为True继续后面操作
WebDriverWait(driver, 10, 0.5).until(
lambda el:driver.find_element_by_xpath(), message = '自定义信息')

  • 用来等待某个条件发生后再继续执行后续代码(如找到元素、元素可点击、元素已显示等)

  • 方式:

    1
    2
    WebDriverWait wait = new WebDriverWait();
    WebElement element = wait.until(expectCondition);
    方法 等待条件
    visibilityOfElementLocated(By locator) 页面元素在页面存在并且可见
    elementToBeClickable(By locator) 页面元素是否在页面上可用和可被单击
    elementToBeSelected(WebElement element) 页面元素处于被选中状态
    textToBePresentInElement(By locator) 在页面元素中是否存在包含特定的文本
    presenceOfElementLocated(By locator) 页面元素在页面中存在

特殊元素操作

模态框

Modal Dialogue Box,模式对话框,是指在用户想要对对话框以外的应用程序进行操作是,必须首先对该对话框进行响应。如单击【确定】或【取消】按钮等对该对话框关闭

alter弹框

1
2
3
4
5
6
7
8
9
10
11
12
opeanChrome();
chromeDriver.get("D:\\Java\\JavaCompile\\WebCompetition\\alter.html");
Thread.sleep(1000);
chromeDriver.findElement(By.id("asd")).click();
//switchTo().alert()找到对应的alert弹框
Alert alert = chromeDriver.switchTo().alert();
//获取文本
System.out.println(alert.getText());
//确定
alert.accept();
//取消
//alert.dismiss();

comfirm弹框

1
2
3
chromeDriver.get("D:\\Java\\JavaCompile\\WebCompetition\\confirm.html");
chromeDriver.findElement(By.id("wasd")).click();
Alert alter = chromeDriver.switchTo().alert();

iframe切换

四种切换模式:

  • driver.switchTo().frame(index);
  • driver.switchTo().frame(id);
  • driver.switchTo().frame(name);
  • driver.switchTo().frame(WebElement)

切换之后,回到默认内容页面(否则会找不到元素)

driver.switchTo().defaultContent();

Window切换

当要操作另外一个窗口页面的元素时,一定要注意先切换窗口

切换方式:传入要操作窗口的name或者句柄handle

driver.switchTo.window(nameOrHandle);

如何获取到窗口页面的句柄:

  • driver.getWindowHandle();获取当前操作窗口的句柄
  • driver.getWindowHandles();获取测试时打开的所有窗口句柄

select下拉框

如果页面元素时是一个下拉框,可以将次Web元素封装为Select对象

  • Select select = new Select(WebElement element);

Select对象常用API

  • select.getOptions();获取所有选项
  • select.selectByIndex(index);获取索引选中对应的元素
  • select.selectByValue(value);选中指定value值对应的选项
  • select.selectByVisibleText(text)选中文本值对应的选项

时间日期控件

分为两种情况:

  • 控件没有限制手动输入,测直接调用sendKeys方法写入时间数据

    1
    2
    3
    4
    5
    //时间日期控件
    opeanChrome();
    chromeDriver.get("https://www.fliggy.com/?ali_trackid=2:mm_580840021_2968100290_115013700224:1695795842_087_879488174&union_lens=lensId:PUB@1694669594@0be085cd_09df_18a922ddf56_d0eb@01@eyJmbG9vcklkIjozODg1Miiwiic3BtQiiI6Il9wb3J0YWxfdjJfcGFnZXNfYWN0aXZpdHlfb2ZmaWNpYWxfaW5kZXhfaHRtIn0ie;recoveryid:087_41852627@1695795842353&rootPageId=20150318020010234&bxsign=tbktK07IRSYD_ottbYadojTdnlVU4NrusREkCNNuZWqcG0iY9VggecxE0I7oNA6SD-MH5FIEV3RbK9JUJbFFjsG0oCrFYAUIAHRNK3UdMjtcUaEWG_JPVEmj7u5AZVETJpaxf6UBwBotkDBJwoUpoHafQ");
    Thread.sleep(1000);
    chromeDriver.findElement(By.xpath("//form[@id='J_FlightForm']//input[@name='depDate']")).sendKeys("2023-09-27");
  • 控件有限制输入,则可以执行一段js来改变元素的value属性值

    JavascriptExeutor jsExecutor = (JavascriptExecutor)driver;

    jsExecutor.executeScript("...");

    1
    2
    3
    4
    5
    chromeDriver.get("www.12306.cn/index/");
    //解除输入的时间日期限制
    JavascriptExecutor javascriptExecutor = (JavascriptExecutor)chromeDriver;
    javascriptExecutor.executeScript("document.getElementById("\train_date\").removeAttribute(\"readonly\")");
    chromeDriver.findElement(By.id("train_date")).sendKeys("2023-10-01");

鼠标操作(未完待续)

使用Selenium的Actions类来模拟鼠标键盘操作,通过Actions对象可以发起鼠标左键、右键、移动鼠标等操作,最后使用perform方法执行操作

actions.clickAndHold(onElement).moveToElement(toElement).release().build().perform()

1
2
3
4
5
6
7
opeanChrome();
chromeDriver.get("https://www.treejs.cn/v3/demo/cn/exedit/drag.html");
WebElement sourceElement = chromeDriver.findElement(By.id("treeDemo_2_span"));
WebElement targetElement = chromeDriver.findElement(By.id("treeDemo_4_span"));

Actions actions = new Actions(chromeDriver);
actions.clickAndHold(sourceElement).moveToElement(targetElement).release().click().perform();

文件上传、验证码

  • 如果有input,使用sendKeys写入文件路径
  • 如果不是input元素,使用第三方工具,如:autoit

截屏操作

JMeter

基本概念:

  • 虚拟用户数:线程=用户

  • 并发数:指在某一时间,一定数量的虚拟用户同时对系统的某个功能进行交互,一般通过集合点实现

  • 事务:一个接口可以是事务,多个接口也可以是事务,一个流程可以是事务,事务代表着一个完整的功能,由测试人员决定。

  • 场景:性能测试的用例

  • 相应时间:Response Time(RT)

  • TPS:是系统的重要性能指标,用于衡量系统在一定的时间内能够处理的事务数(交易数)

    计算公式:总的事务数/总的运行时间

  • QTS:每一秒的查询率

  • 吞吐量:衡量网络成功传输的数量,单位:Byte/S

  • 资源利用率:服务器、CPU、内存、磁盘、网络


Web性能测试是为了考察大家对JMeter工具的基础使用情况,我们从 (1) 线程名称、 (2) 线程数、 (3) 启动时间、 (4) 运行时、 (5) 事务控制器、 (6) 集合点、 (7) 参数化、 (8) 请求成功率等方面作为得分点,来检测大家对生成测试脚本的测试能力。

性能测试总分共计100分,其中线程名称占比10%、线程数占比10%、启动时间占比10%、运行时间占比10%、事务控制器占10%、集合点占比20%、参数化占比20%、请求成功率占比10%。


JMeter取样器及脚本录制

考点

JMeter运行参数的设置

  • 线程组的设置
  • 集合点的设置

数据驱动的JMeter参数化测试

练习赛截图

集合点:(Synchronizing Timer)

录制流量

英文:HTTP(s) Test Script Recorder

JMeter的运行参数设置

  • 线程组的设置
  • 集合点的设置

数据驱动的JMeter参数化设置

未完待续

模拟时间间隔

  1. 固定定时器

当要访问一个网站的首页、第二页面、第三页面等网页时,模拟正常的用户访问顺序、时间,这时,可以设置固定定时器

  1. 测试活动取样器

压力测试