2024年全国大学生软件测试大赛—练习—12306网站

一、边界值和等价类

边界值分析(Boundary Value Analysis, BVA)和等价类划分(Equivalence Partitioning, EP)是两种常用的软件测试设计技术,它们用于确定测试用例,以发现程序中的错误。这两种技术通常一起使用,以提高测试的效率和有效性。

### 等价类划分(Equivalence Partitioning, EP)

等价类划分是将输入数据的集合划分为若干个等价类,每个等价类中的数据从程序的角度来看是等效的。也就是说,程序对等价类中的任何一个输入数据的处理方式是相同的。在设计测试用例时,只需要从每个等价类中选取代表性的值作为测试数据即可。

等价类通常分为三种类型:

1. **有效等价类**:包含所有合法的、符合程序规格说明的输入数据。
2. **无效等价类**:包含所有不合法的、不符合程序规格说明的输入数据。
3. **特殊等价类**:包含边界值、空值、特殊字符等特殊情况。

### 边界值分析(Boundary Value Analysis, BVA)

边界值分析是基于等价类划分的,它关注的是输入或输出的边界情况。经验表明,错误往往发生在输入或输出的边界附近,而不是在等价类的中心。因此,边界值分析要求测试等价类的边界值以及边界附近的值。

边界值分析通常包括以下几种情况:

1. **最小值边界**:等价类的最小值。
2. **最小值+1边界**:等价类最小值的下一个值。
3. **最大值边界**:等价类的最大值。
4. **最大值-1边界**:等价类最大值的前一个值。

### 应用示例

假设有一个程序要求输入年龄,年龄的有效范围是1到100岁。

- **等价类划分**:
  - 有效等价类:1-100岁之间的任意整数。
  - 无效等价类:小于1岁或大于100岁的值。

- **边界值分析**:
  - 最小值边界:1岁。
  - 最小值+1边界:2岁。
  - 最大值边界:100岁。
  - 最大值-1边界:99岁。

在设计测试用例时,您会从每个等价类中选取代表性的值,并确保测试边界值及其附近的值。例如,对于年龄输入,测试用例可能包括:0岁(无效)、1岁(最小边界)、2岁(最小边界+1)、99岁(最大边界-1)、100岁(最大边界)和101岁(无效)。

通过结合等价类划分和边界值分析,可以有效地识别程序中的潜在错误,提高测试的全面性和效率。

二、分析题目 

1. 测试目的

验证12306单程车票快速查询模块的功能正确性,包括普通车票查询学生票查询以及动车高铁列车的车票查询

2. 测试范围

本文档涵盖了12306单程车票快速查询模块的功能点:

  • 普通车票查询
  • 学生票查询
  • 动车高铁列车车票查询
  • 动车高铁列车学生票查询

出发地、到达地和出发日期的输入方式均采用在输入框中键入输入值回车的方式。

3. 测试方法

3.1 普通车票查询:输入出发地目的地出发日期,完成查询;

3.2 学生票查询:输入出发地目的地出发日期,完成学生票查询;

3.3 动车高铁列车车票查询:输入出发地目的地出发日期,查询动车高铁列车的车票;

3.4 动车高铁列车学生票查询:输入出发地目的地出发日期查询动车高铁列车的学生票;

4. 输入数据

4.1 出发地输入数据:

输入任意合法的车站名称;(三种)

4.2 到达地输入数据:

    输入任意合法的车站名称;(同上)

4.3 出发日期输入数据:

按照yyyy-mm-dd的格式输入合法日期;

出发日期应考虑以下三个等价类

1、早于当前日期

2、不早于当前日期且在预售期内

3、超出预售期

 

 出发日期考虑三个等价类:(那我们可以推断有5个测试用例,原因如下:)

1.早于今天的票(15号及以前)

2. 今天的票(16号,图中显示今天)

3.今天后的到预售期前的中间这几天的票(根据上图17号——29号)

4.预售期那天(30号)的票

5.超出预售期后的票(31号及以后)

 5.示例代码

这个是对普通车票的查询 

package Test12306;//声明该类所属的包名为Test12306。

import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;
import java.util.concurrent.TimeUnit;


public class TestTemplate { //定义一个名为TestTemplate的公共类
    private WebDriver driver; //声明一个私有的WebDriver类型的实例变量driver,用于控制浏览器

    @BeforeEach //JUnit5 的注解,表示在每个测试方法执行之前都会执行这个方法
    public void setup() {


        System.setProperty("webdriver.chrome.driver", "D:\\RuanJian\\google\\chrome-win64\\chrome-win64\\chromedriver.exe");//JUnit5 的注解,表示在每个测试方法执行之前都会执行这个方法

        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.addArguments("--remote-allow-origins=*");
        driver = new ChromeDriver(chromeOptions);

        driver.get("https://www.12306.cn/index/index.html");//使用driver打开指定的网址https://www.12306.cn/index/index.html。
        driver.manage().window().maximize();//将浏览器窗口最大化。
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);//设置隐式等待时间为 10 秒,即在一定时间内如果元素没有出现,Selenium 会等待直到超时

    }


//     请在这里插入JUnit5测试代码

    @Test
    public void testUI(){
        takeScreenshot("12306_search_UI_001.png");
    }

    @ParameterizedTest //JUnit5 的注解,表示该方法是一个参数化测试,即该方法可以接受多个参数,并在每次测试时使用不同的参数组合。
    @CsvSource({
            "西安北, 北京北, 2024-10-1, 12306_search_001.png",
            "西安北, 北京北, 2024-10-17, 12306_search_002.png",
            "西安北, 北京北, 2024-10-20, 12306_search_003.png",
            "西安北, 北京北, 2024-10-31, 12306_search_004.png",
            "西安北, 北京北, 2024-11-5, 12306_search_005.png",
    })
    public void test_12306_search(String from, String to, String date, String screenShot) throws InterruptedException {
        //找到出发地输入框并输入第一个值

        WebElement fromField = driver.findElement(By.id("fromStationText"));
        fromField.clear();
        fromField.sendKeys(from + Keys.ENTER);

//        WebDriverWait wait = new WebDriverWait(driver, 10);
//        WebElement fromField = wait.until(ExpectedConditions.elementToBeClickable(By.id("fromStationText")));

        //找到目的地输入框并输入第二个值

        WebElement toField = driver.findElement(By.id("toStationText"));
        toField.clear();
        toField.sendKeys(to + Keys.ENTER);

        //找到日期输入框并输入第三个值
        driver.findElement(By.id("train_date")).clear();
        driver.findElement(By.id("train_date")).sendKeys(date);

        //找到搜索按钮并点击
        Thread.sleep(2000);
        driver.findElement(By.id("search_one")).click();

        //点击后还是当前的页面,而这个搜索按钮点击后是要跳转到另一个页面
        driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
        //driver.switchTo().window()用于在当前会话中切换到不同的窗口或框架中。它接受一个字符串参数,该参数是要切换到的窗口或框架的句柄。
        //driver.getWindowHandles()这是一个Selenium WebDriver的方法,返回当前会话中所有打开的窗口或标签页的句柄集合(Set<String>类型)
        //.toArray()这是将集合(Set<String>)转换为数组的方法。这里将窗口句柄集合转换为数组,以便可以通过索引访问特定的窗口句柄。
        //[1].toString()这里访问数组的第二个元素(索引为1),因为索引从0开始,.toString() 方法将数组元素(本例中是一个窗口句柄)转换为字符串,因为 switchTo().window() 方法需要一个字符串类型的窗口句柄作为参数

        //截取屏幕截图并保存为指定文件名
        Thread.sleep(2000);
        takeScreenshot(screenShot);


    }






    @AfterEach //JUnit5 的注解,表示在每个测试方法执行之后都会执行这个方法。
    public void teardown() throws InterruptedException {
        Thread.sleep(5000);
        this.driver.quit();
    } //关闭浏览器并退出驱动程序。


        private void takeScreenshot(String fileName) { //定义一个私有的方法,用于截取浏览器屏幕截图并保存为指定文件名。
        File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);//使用driver的截图功能获取屏幕截图,并将其保存为一个File对象。
        try {
            FileUtils.copyFile(screenshotFile, new File(fileName));//尝试使用FileUtils将截图文件复制到指定的文件名对应的文件中。
        } catch (Exception e) {
            e.printStackTrace();//如果在复制文件过程中出现异常,打印异常的堆栈跟踪信息。
        }
    }
}

 

附上全部的代码

package Test12306;//声明该类所属的包名为Test12306。

import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;
import java.util.concurrent.TimeUnit;


public class TestTemplate { //定义一个名为TestTemplate的公共类
    private WebDriver driver; //声明一个私有的WebDriver类型的实例变量driver,用于控制浏览器

    @BeforeEach //JUnit5 的注解,表示在每个测试方法执行之前都会执行这个方法
    public void setup() {


        System.setProperty("webdriver.chrome.driver", "D:\\RuanJian\\google\\chrome-win64\\chrome-win64\\chromedriver.exe");//JUnit5 的注解,表示在每个测试方法执行之前都会执行这个方法

        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.addArguments("--remote-allow-origins=*");
        driver = new ChromeDriver(chromeOptions);

        driver.get("https://www.12306.cn/index/index.html");//使用driver打开指定的网址https://www.12306.cn/index/index.html。
        driver.manage().window().maximize();//将浏览器窗口最大化。
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);//设置隐式等待时间为 10 秒,即在一定时间内如果元素没有出现,Selenium 会等待直到超时

    }


//     请在这里插入JUnit5测试代码

    //用于测试用户界面
    @Test
    public void testUI(){
        takeScreenshot("12306_search_UI_001.png");
    }

    //用于测试普通的查票查询
    @ParameterizedTest //JUnit5 的注解,表示该方法是一个参数化测试,即该方法可以接受多个参数,并在每次测试时使用不同的参数组合。
    @CsvSource({
            "西安北, 北京北, 2024-10-1, 12306_search_001.png",
            "西安北, 北京北, 2024-10-17, 12306_search_002.png",
            "西安北, 北京北, 2024-10-20, 12306_search_003.png",
            "西安北, 北京北, 2024-10-31, 12306_search_004.png",
            "西安北, 北京北, 2024-11-5, 12306_search_005.png",
    })
    public void test_12306_search(String from, String to, String date, String screenShot) throws InterruptedException {
        //找到出发地输入框并输入第一个值

        WebElement fromField = driver.findElement(By.id("fromStationText"));
        fromField.clear();
        fromField.sendKeys(from + Keys.ENTER);

//        WebDriverWait wait = new WebDriverWait(driver, 10);
//        WebElement fromField = wait.until(ExpectedConditions.elementToBeClickable(By.id("fromStationText")));

        //找到目的地输入框并输入第二个值

        WebElement toField = driver.findElement(By.id("toStationText"));
        toField.clear();
        toField.sendKeys(to + Keys.ENTER);

        //找到日期输入框并输入第三个值
        driver.findElement(By.id("train_date")).clear();
        driver.findElement(By.id("train_date")).sendKeys(date);

        //找到搜索按钮并点击
        Thread.sleep(2000);
        driver.findElement(By.id("search_one")).click();

        //点击后还是当前的页面,而这个搜索按钮点击后是要跳转到另一个页面
        driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
        //driver.switchTo().window()用于在当前会话中切换到不同的窗口或框架中。它接受一个字符串参数,该参数是要切换到的窗口或框架的句柄。
        //driver.getWindowHandles()这是一个Selenium WebDriver的方法,返回当前会话中所有打开的窗口或标签页的句柄集合(Set<String>类型)
        //.toArray()这是将集合(Set<String>)转换为数组的方法。这里将窗口句柄集合转换为数组,以便可以通过索引访问特定的窗口句柄。
        //[1].toString()这里访问数组的第二个元素(索引为1),因为索引从0开始,.toString() 方法将数组元素(本例中是一个窗口句柄)转换为字符串,因为 switchTo().window() 方法需要一个字符串类型的窗口句柄作为参数

        //截取屏幕截图并保存为指定文件名
        Thread.sleep(2000);
        takeScreenshot(screenShot);


    }

    //查询学生票
    @ParameterizedTest
    @CsvSource({
            "西安北, 北京北, 2024-10-1, 12306_search_student_001.png",
            "西安北, 北京北, 2024-10-17, 12306_search_student_002.png",
            "西安北, 北京北, 2024-10-20, 12306_search_student_003.png",
            "西安北, 北京北, 2024-10-31, 12306_search_student_004.png",
            "西安北, 北京北, 2024-11-5, 12306_search_student_005.png",
    })
    public void test_12306_search_student(String from, String to, String date, String screenShot) throws InterruptedException {
        //找到出发地地输入框并输入第二个值
        WebElement fromField = driver.findElement(By.id("fromStationText"));
        fromField.clear();
        fromField.sendKeys(from + Keys.ENTER);

        //找到目的地输入框并输入第二个值
        WebElement toField = driver.findElement(By.id("toStationText"));
        toField.clear();
        toField.sendKeys(to + Keys.ENTER);

        //找到日期输入框并输入第三个值
        driver.findElement(By.id("train_date")).clear();
        driver.findElement(By.id("train_date")).sendKeys(date);

        //找到学生复选框进行勾选
        driver.findElement(By.id("isStudentDan")).click();
        //找到搜索按钮并点击
        Thread.sleep(2000);
        driver.findElement(By.id("search_one")).click();

        //点击后还是当前的页面,而这个搜索按钮点击后是要跳转到另一个页面
        driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());

        //截取屏幕截图并保存为指定文件名
        Thread.sleep(2000);
        takeScreenshot(screenShot);


    }

    //查询高铁动车票
    @ParameterizedTest
    @CsvSource({
            "西安北, 北京北, 2024-10-1, 12306_search_gd_001.png",
            "西安北, 北京北, 2024-10-17, 12306_search_gd_002.png",
            "西安北, 北京北, 2024-10-20, 12306_search_gd_003.png",
            "西安北, 北京北, 2024-10-31, 12306_search_gd_004.png",
            "西安北, 北京北, 2024-11-5, 12306_search_gd_005.png",
    })
    public void test_12306_search_gd(String from, String to, String date, String screenShot) throws InterruptedException{
        //找到出发地地输入框并输入第二个值
        WebElement fromField = driver.findElement(By.id("fromStationText"));
        fromField.clear();
        fromField.sendKeys(from + Keys.ENTER);

        //找到目的地输入框并输入第二个值
        WebElement toField = driver.findElement(By.id("toStationText"));
        toField.clear();
        toField.sendKeys(to + Keys.ENTER);

        //找到日期输入框并输入第三个值
        driver.findElement(By.id("train_date")).clear();
        driver.findElement(By.id("train_date")).sendKeys(date);

        //找到高铁/动车复选框进行勾选
        driver.findElement(By.id("isHighDan")).click();
        //找到搜索按钮并点击
        Thread.sleep(2000);
        driver.findElement(By.id("search_one")).click();

        //点击后还是当前的页面,而这个搜索按钮点击后是要跳转到另一个页面
        driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());

        //截取屏幕截图并保存为指定文件名
        Thread.sleep(2000);
        takeScreenshot(screenShot);
    }

    //查询学生票和高铁动车票
    @ParameterizedTest
    @CsvSource({
            "西安北, 北京北, 2024-10-1, 12306_search_gd_student_001.png",
            "西安北, 北京北, 2024-10-17, 12306_search_gd_student_002.png",
            "西安北, 北京北, 2024-10-20, 12306_search_gd_student_003.png",
            "西安北, 北京北, 2024-10-31, 12306_search_gd_student_004.png",
            "西安北, 北京北, 2024-11-5, 12306_search_gd_student_005.png",
    })
    public void test_12306_search_gd_student(String from, String to, String date, String screenShot) throws InterruptedException{
        //找到出发地地输入框并输入第二个值
        WebElement fromField = driver.findElement(By.id("fromStationText"));
        fromField.clear();
        fromField.sendKeys(from + Keys.ENTER);

        //找到目的地输入框并输入第二个值
        WebElement toField = driver.findElement(By.id("toStationText"));
        toField.clear();
        toField.sendKeys(to + Keys.ENTER);

        //找到日期输入框并输入第三个值
        driver.findElement(By.id("train_date")).clear();
        driver.findElement(By.id("train_date")).sendKeys(date);

        //找到学生复选框进行勾选
        driver.findElement(By.id("isStudentDan")).click();
        //找到高铁/动车复选框进行勾选
        driver.findElement(By.id("isHighDan")).click();
        //找到搜索按钮并点击
        Thread.sleep(2000);
        driver.findElement(By.id("search_one")).click();

        //点击后还是当前的页面,而这个搜索按钮点击后是要跳转到另一个页面
        driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());

        //截取屏幕截图并保存为指定文件名
        Thread.sleep(2000);
        takeScreenshot(screenShot);
    }
    @AfterEach //JUnit5 的注解,表示在每个测试方法执行之后都会执行这个方法。
    public void teardown() throws InterruptedException {
        Thread.sleep(2000);
        this.driver.quit();
    } //关闭浏览器并退出驱动程序。

    //一个私有方法,用于截取当前浏览器窗口的屏幕截图,并将其保存为指定的文件名
    private void takeScreenshot(String fileName) { //定义一个私有的方法,用于截取浏览器屏幕截图并保存为指定文件名。
        File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);//使用driver的截图功能获取屏幕截图,并将其保存为一个File对象。
        try {
            FileUtils.copyFile(screenshotFile, new File(fileName));//尝试使用FileUtils将截图文件复制到指定的文件名对应的文件中。
        } catch (Exception e) {
            e.printStackTrace();//如果在复制文件过程中出现异常,打印异常的堆栈跟踪信息。
        }
    }
}

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值