问卷系统自动化测试报告

一、项目介绍

项目背景

问卷系统功能简介:问卷系统主要用于满足用户在线创建问卷和考试的需求,同时,系统提供注册和登录功能,作为用户使用核心功能的身份验证入口。

测试计划

验证问卷系统核心功能(创建问卷,回答问卷)的完整性和正确性,确保符合需求规格;
评估系统在预期用户量下的性能表现(响应时间、稳定性),满足基本使用体验;
通过自动化测试覆盖高频场景,保障系统迭代过程中的功能稳定性,降低回归测试成本。

项目功能及页面展示

登录页面

通过用户名和密码登录完成用户的身份验证,同时密码可视化
当用户没有账户,可跳转至注册账户
在这里插入图片描述

注册页面

通过姓名、登录账号、密码、密码确认完成新用户的注册,同时支持密码可视化
当用户注册完成,可跳转登录界面
在这里插入图片描述

问卷系统首页

核心功能:创建问卷,创建考试
其他功能:

  • 我的项目,管理创建好的问卷或考试
  • 我的练习:我做过的练习
  • 题库中心:创建问卷或考试时可用的题库
  • 模版广场:创建问卷或考试时可用的模版
  • 用户设置:设置昵称,手机号,邮箱

在这里插入图片描述

问卷创建页面

核心功能:多题型设置的问卷设计
其他功能:

  • 预览问卷
  • JSON查看
  • 保存问卷
  • 题库功能
  • 大纲功能
    在这里插入图片描述

问卷项目管理

核心功能:管理创建好的问卷或考试,进行预览,重命名,停止问卷,复制问卷,删除问卷操作
其他功能:

  • 通过新建直接跳转创建考试页面
  • 通过Excel导入
  • 通过文本导入
  • 通过模版导入
  • 新建文件夹
  • 回收站

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

问卷应答页面

核心功能:提交问卷答案后自动评分,给出分数,答题时长,提交时间

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

二、设计测试用例

在这里插入图片描述

在这里插入图片描述

三、自动化测试脚本编写

Utils.py

Driver类是一个基于 Selenium 的 Chrome 浏览器驱动封装类

  • 单例使用:通过ShoppingDriver=Driver()创建了一个实例,供多个测试文件共享使用
  • 自动管理驱动:使用webdriver_manager自动安装和管理 ChromeDriver
  • 包含截图功能:提供了便捷的页面截图方法
  • 简单的初始化配置:设置了 3 秒的隐式等待时间
import datetime
import os
import sys

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager


class Driver:
    driver = ""
    def __init__(self):
        options = webdriver.ChromeOptions()
        # options.add_argument("-headless") #无头模式无法运行,因为窗口太小会找不到我的项目元素以及保存考试的元素
        # options.page_load_strategy = 'eager' # 更改页面加载策略,加快访问速度,但是有可能会导致没有等待到元素加载出来就获取
        self.driver = webdriver.Chrome(service = Service(ChromeDriverManager().install()),options = options)

        self.driver.implicitly_wait(3)
    def getScreeShot(self):
        #先创建文件
        dirname = datetime.datetime.now().strftime('%Y-%m-%d')
        #如果没有找到文件夹就生成一个,不是在common文件夹生成文件夹,而是在总目录下生成一个带日期的文件夹
        if not os.path.exists("../images/"+dirname):
            os.mkdir("../images/"+dirname)

        filename = sys._getframe().f_back.f_code.co_name+"-"+datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
        self.driver.save_screenshot("../images/"+dirname+"/"+filename+".png")
        #为了更好定位到照片信息,获取调用的方法名加进名字里
        #sys._getframe().f_back.f_code.co_name

TestDriver=Driver()#四个测试文件都只用一个实例出来的对象

TestRegister

TestRegister类主要用于测试用户注册功能的各种场景

  • 复用了之前定义的TestDriver浏览器实例,保持测试环境一致性
  • 初始化时自动打开注册页面
  • 包含RegisterSuccess方法测试注册成功的场景
  • 包含RegisterFail方法测试多种注册失败的场景
  • 失败场景通过字典列表定义,包括密码不足 6 位、不填用户名、不填登录账号等 5 种情况
  • 针对输入框清空操作做了特殊处理(先全选再删除),解决了clear()方法可能失效的问题
import time

from selenium.webdriver import Keys
from selenium.webdriver.common.by import By
from common.Utils import TestDriver

class TestRegister:
    url=""
    driver=""
    def __init__(self):
        self.driver=TestDriver.driver
        self.url="http://8.155.1.153:8081/user/register"
        self.driver.get(self.url)

    def RegisterSuccess(self):
        self.driver.find_element(By.CSS_SELECTOR, "#name").send_keys("name0")
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("username0")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("password1")
        self.driver.find_element(By.CSS_SELECTOR, "#rePassword").send_keys("password1")
        #点击注册
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button").click()
        #注册成功返回登录界面时,验证是不是登录界面
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")
        #添加截图
        TestDriver.getScreeShot()

    def RegisterFail(self):
        test_dic = [
            {"desc": "密码不足6位", "name": "test_user", "username": "test_username", "password": "123",
             "rePassword": "123"},
            {"desc": "不写用户名注册", "name": "", "username": "test_username", "password": "123456",
             "rePassword": "123456"},
            {"desc": "不写登录账号注册", "name": "test_user", "username": "", "password": "123456",
             "rePassword": "123456"},
            {"desc": "不写密码注册", "name": "test_user", "username": "test_username", "password": "",
             "rePassword": ""},
            {"desc": "不写密码确认注册", "name": "test_user", "username": "test_username", "password": "123456",
             "rePassword": ""}
        ]

        for dic in test_dic:
            # 清空输入框
            element=self.driver.find_element(By.CSS_SELECTOR, "#name")
            element.send_keys(Keys.CONTROL + 'a') #输入框看着有内容,实际是隐藏字符或浏览器自动填充,clear 方法对这类情况处理不好。
            element.send_keys(Keys.DELETE) #先全选,再删除的方式清空输入栏
            element=self.driver.find_element(By.CSS_SELECTOR, "#username")
            element.send_keys(Keys.CONTROL + 'a')
            element.send_keys(Keys.DELETE)
            element=self.driver.find_element(By.CSS_SELECTOR, "#password")
            element.send_keys(Keys.CONTROL + 'a')
            element.send_keys(Keys.DELETE)
            element=self.driver.find_element(By.CSS_SELECTOR, "#rePassword")
            element.send_keys(Keys.CONTROL + 'a')
            element.send_keys(Keys.DELETE)
            time.sleep(3)

            # 输入用户名
            if dic["name"]:
                time.sleep(1)
                self.driver.find_element(By.CSS_SELECTOR, "#name").clear()
                time.sleep(1)
                self.driver.find_element(By.CSS_SELECTOR, "#name").send_keys(dic["name"])
            # 输入登录账号
            if dic["username"]:
                time.sleep(1)
                self.driver.find_element(By.CSS_SELECTOR, "#username").clear()
                time.sleep(1)
                self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys(dic["username"])

            # 输入密码
            if dic["password"]:
                time.sleep(1)
                self.driver.find_element(By.CSS_SELECTOR, "#password").clear()
                time.sleep(1)
                self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys(dic["password"])
            # 输入密码确认
            if dic["rePassword"]:
                time.sleep(1)
                self.driver.find_element(By.CSS_SELECTOR, "#rePassword").clear()
                time.sleep(1)
                self.driver.find_element(By.CSS_SELECTOR, "#rePassword").send_keys(dic["rePassword"])

            # 点击注册
            self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button").click()
            # 验证注册账号的按钮是否存在
            self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button")
            time.sleep(3)
            #添加截图
            TestDriver.getScreeShot()

TestLogin

TestLogin类与之前的TestRegister类在设计思路上高度协同,专门用于覆盖登录场景的正常与异常测试

import time

from selenium.webdriver.common.by import By
from common.Utils import TestDriver

class TestLogin:
    url=""
    driver=""
    def __init__(self):
        self.driver=TestDriver.driver
        self.url="http://8.155.1.153:8081/user/login"
        self.driver.get(self.url)
        self.driver.fullscreen_window()
    def LoginSuccess(self):
            self.driver.find_element(By.CSS_SELECTOR, "#username").clear()
            self.driver.find_element(By.CSS_SELECTOR, "#password").clear()
            #输入框输入账号
            self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("dz000")
            #输入框输入密码
            self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("bit12344321..")
            #点击登录
            self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button").click()
            #进入问卷首页后,验证头像,是不是进入了首页
            self.driver.find_element(By.CSS_SELECTOR, "#sk-layout > div > div > section > div.ant-pro-layout-container > header.ant-layout-header.ant-pro-layout-header.ant-pro-layout-header-fixed-header.ant-pro-layout-header-mix.ant-pro-layout-header-header > div > div.ant-pro-global-header-right-content > div > div > div > span > div > span.ant-avatar.ant-avatar-circle.ant-avatar-image > img")
            #添加截图
            TestDriver.getScreeShot()


    def LoginFail(self):
        for i in range(0,2):
            # 验证失败账号登录之后还要错误的密码登录,要清空输入框
            self.driver.find_element(By.CSS_SELECTOR, "#username").clear()
            self.driver.find_element(By.CSS_SELECTOR, "#password").clear()
            if i == 0:
                # 输入框输入正确的账号,错误的密码
                self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("dz000")
                self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("bit12344321.")
            else:
                # 输入框输入错误的账号,正确的密码
                self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("dz00")
                self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("bit12344321..")

            # 点击登录
            self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button").click()

            # 验证是不是还在登录界面,显示错误的用户名和密码
            text=self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > div.ant-alert.ant-alert-error > div > div").text
            assert (text=="错误的用户名和密码")

            # 添加截图
            TestDriver.getScreeShot()

TestHome

TestHome类用于验证系统首页在 “登录” 与 “未登录” 两种状态下的访问权限、页面跳转逻辑及元素完整性

  • 与TestLogin类联动:TestLogin.LoginSuccess()执行成功后,可调用TestHome.TestHomeByLogin()验证“登录后跳转首页” 的完整流程。
  • 与后续业务测试(如 “创建问卷”“创建考试”)衔接:首页核心元素验证通过,才能确保后续功能测试的起点(首页)是正常可用的。
from selenium.webdriver.common.by import By
from common.Utils import TestDriver

class TestHome:
    url = ""
    driver = ""

    def __init__(self):
        self.driver = TestDriver.driver
        self.url = "http://8.155.1.153:8081/home"
        self.driver.get(self.url)

    def TestHomeNotLogin(self):
        #未登录状态下,跳转到登录界面,验证是不是在登录界面
        url=self.driver.current_url
        assert (url == "http://8.155.1.153:8081/user/login")
        # 添加截图
        TestDriver.getScreeShot()

    def TestHomeByLogin(self):
        #登录状态下,页面元素为:标题、头像、用户名、创建问卷、创建考试
        # 标题
        self.driver.find_element(By.CSS_SELECTOR, "#sk-layout > div > div > section > div.ant-pro-layout-container > header.ant-layout-header.ant-pro-layout-header.ant-pro-layout-header-fixed-header.ant-pro-layout-header-mix.ant-pro-layout-header-fixed-header-action.ant-pro-layout-header-header > div > div.ant-pro-global-header-logo.ant-pro-global-header-logo-mix > a > h1")
        # 头像
        self.driver.find_element(By.CSS_SELECTOR, "#sk-layout > div > div > section > div.ant-pro-layout-container > header.ant-layout-header.ant-pro-layout-header.ant-pro-layout-header-fixed-header.ant-pro-layout-header-mix.ant-pro-layout-header-fixed-header-action.ant-pro-layout-header-header > div > div.ant-pro-global-header-right-content > div > div > div > span > div > span.ant-avatar.ant-avatar-circle.ant-avatar-image > img")
        # 用户名
        self.driver.find_element(By.CSS_SELECTOR, "#sk-layout > div > div > section > div.ant-pro-layout-container > header.ant-layout-header.ant-pro-layout-header.ant-pro-layout-header-fixed-header.ant-pro-layout-header-mix.ant-pro-layout-header-header > div > div.ant-pro-global-header-right-content > div > div > div > span > div > span:nth-child(2)")
        # 创建问卷
        self.driver.find_element(By.CSS_SELECTOR, "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-col.ant-col-xs-24.ant-col-sm-24.ant-col-md-24.ant-col-lg-24.ant-col-xl-8 > div > div.ant-card-body > div > a:nth-child(1)")
        # 创建考试
        self.driver.find_element(By.CSS_SELECTOR, "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-col.ant-col-xs-24.ant-col-sm-24.ant-col-md-24.ant-col-lg-24.ant-col-xl-8 > div > div.ant-card-body > div > a:nth-child(2)")
        # 添加截图
        TestDriver.getScreeShot()

ExamEdit

ExamEdit类核心覆盖 “考试创建、保存、开启、参与” 的完整业务链路,兼顾 “登录 / 未登录权限控制”“页面元素完整性校验”“异常场景验证” 三个测试维度

以ExamYesEditByLogin(正常考试流程)为例,完整模拟用户操作链路:
首页→创建考试→输入标题→添加选择题→保存考试→返回首页→进入“我的项目”→找到目标考试→开启考试→打开考试窗口→选择选项→提交→验证结果→关闭窗口

测试方法测试场景分类核心测试目标
ExamEditNotLogin权限控制未登录用户无法访问 “考试编辑页”,自动跳转至登录页
ExamYesEditByLogin正常业务流程已登录用户完成 “创建考试→添加题目→保存→开启→参与考试→提交验证” 全流程
ExamNoEditByLogin异常业务流程验证 3 类异常场景:1. 不保存考试则项目列表无记录2. 保存但不开启考试则无法参与(提示 “问卷已暂停回收”)3. 开启无题目的考试则无提交按钮
ExamEditCheck页面元素校验验证 “考试创建页” 核心功能元素(题型、大纲、保存 / 预览按钮)完整性
import datetime
import time

from selenium.webdriver.common.by import By

from common.Utils import TestDriver


class ExamEdit:
    url = ""
    driver = ""

    def __init__(self):
        self.driver = TestDriver.driver
        self.url = "http://8.155.1.153:8081/survey/new?mode=exam"
        self.driver.get(self.url)

    def ExamEditNotLogin(self):
        # 未登录状态下,返回到登录界面
        #time.sleep(2)
        # 验证是不是在登录界面
        time.sleep(1)
        url = self.driver.current_url
        assert (url == "http://8.155.1.153:8081/user/login")
        self.driver.find_element(By.CSS_SELECTOR, "#username")
        self.driver.find_element(By.CSS_SELECTOR, "#password")
        # 添加截图
        TestDriver.getScreeShot()

    def ExamYesEditByLogin(self):
        # 进来的时候就是创建考试界面了,要回到主页
        examurl = "http://8.155.1.153:8081/home"
        self.driver.get(examurl)
        self.driver.fullscreen_window()
        # 保存考试后开启有题目的考试 —— 清空标题名,名字设置为有题目的考试,保存,回退两次到主页,再点我的项目,再用find_elemengt选中名字进入,
        # 点击开启考试,点击网址跳转到新窗口,切换窗口,选择选项后点击提交考试
        (self.driver.find_element(By.CSS_SELECTOR,
        "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-col.ant-col-xs-24.ant-col-sm-24.ant-col-md-24.ant-col-lg-24.ant-col-xl-8 > div > div.ant-card-body > div > a:nth-child(2)")
         .click())  # 创建考试
        (self.driver.find_element(By.CSS_SELECTOR,
        "#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor > p")
         .clear())  # 清空考试名称
        (self.driver.find_element(By.CSS_SELECTOR,
        "#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor > p")
         .send_keys("有题目的考试"))  # 设置考试名字
        time.sleep(1)
        self.driver.find_element(By.CSS_SELECTOR,"#rc-tabs-1-panel-1 > div > div > dl:nth-child(1) > div > div:nth-child(1) > dd > div").click() # 添加选择题
        time.sleep(1)
        (self.driver.find_element(By.CSS_SELECTOR,
        "#editor > div.survey-main-panel > div.survey-main-panel-toolbar > div:nth-child(2) > div > button.ant-btn.ant-btn-primary.ant-btn-sm > span")
         .click())  # 保存考试
        self.driver.back()  # 回退到主页
        self.driver.back()  # 回退到主页
        (self.driver.find_element(By.CSS_SELECTOR,
        "#sk-layout > div > div > section > aside > div > div:nth-child(1) > ul > li:nth-child(2) > span > a > div > span.anticon.ant-pro-base-menu-item-icon > span > svg")
         .click())  # 点击我的项目
        examnums = self.driver.find_elements(By.CSS_SELECTOR, "span.survey-title")  # 查找
        name_element = None
        for name in examnums:
            if name.text == "有题目的考试":
                name_element = name
                break

        if name_element:
            name_element.click()
        else:
            print("有题目的考试——异常不存在")
            TestDriver.getScreeShot()  # 截图记录
        time.sleep(1)
        # 点击开启考试按钮
        self.driver.find_element(By.CSS_SELECTOR,
        "#root > div > div.survey-main-content > div > div > div:nth-child(2) > div:nth-child(2) > div.ant-row > div > div > div:nth-child(2) > div:nth-child(2) > button").click()
        # 点击打开网址按钮
        self.driver.find_element(By.CSS_SELECTOR,
        "#root > div > div.survey-main-content > div > div > div:nth-child(2) > div:nth-child(2) > div.ant-row > div > div > div:nth-child(1) > span.ant-input-group-wrapper.ant-input-search.ant-input-search-with-button.open-target > span > span > button > span").click()
        # 出现了新窗口,跳转到新窗口
        curwindow = self.driver.current_window_handle  # 获取当前窗口的句柄
        allwindow = self.driver.window_handles  # 获取所有窗口句柄
        for window in allwindow:
            if window != curwindow:
                self.driver.switch_to.window(window)  # 切换到新的窗口
                break
        # 对新窗口进行操作
        # 点击选项1
        self.driver.find_element(By.CSS_SELECTOR,"#root > div > div > div > div.survey-antd-body > div > section > div.survey-antd-body-question-body > div > div > div > div:nth-child(1) > label > span:nth-child(2) > div").click()
        time.sleep(1)
        # 点击提交
        self.driver.find_element(By.CSS_SELECTOR,"#root > div > div > div > div.survey-antd-footer > div.survey-antd-footer-pagination > div > button > div").click()
        # root > div > div > div > div.survey-antd-footer > div.survey-antd-footer-pagination > div > button
        time.sleep(1)
        text=self.driver.find_element(By.CSS_SELECTOR,"#result-message").text
        assert(text=="问卷到此结束,感谢您的参与!")
        # 关闭新窗口,获取所有窗口句柄,切换回老窗口
        self.driver.close()
        allwindow = self.driver.window_handles  # 获取所有窗口句柄
        for window in allwindow:
            if window:
                self.driver.switch_to.window(window)
                break
            else:
                print("异常,所有窗口已经关闭")
                TestDriver.getScreeShot()  # 截图记录

    def ExamNoEditByLogin(self):
        # 进来的时候就是创建考试界面了,要回到主页
        examurl = "http://8.155.1.153:8081/home"
        self.driver.get(examurl)
        self.driver.fullscreen_window()
        time.sleep(2)
        try:
            #登录状态下,异常发布考试:
            # 1.创建考试后不保存考试 —— 清空标题名,名字设置为不保存的考试,回退一次到主页,再点我的项目,再用find_elemengts判断元素不存在
            (self.driver.find_element(By.CSS_SELECTOR,
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-col.ant-col-xs-24.ant-col-sm-24.ant-col-md-24.ant-col-lg-24.ant-col-xl-8 > div > div.ant-card-body > div > a:nth-child(2)")
             .click())  # 创建考试
            (self.driver.find_element(By.CSS_SELECTOR,
            "#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor > p")
             .clear())  # 清空考试名称
            (self.driver.find_element(By.CSS_SELECTOR,
            "#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor > p")
             .send_keys("不保存的考试"))  # 设置考试名字
            self.driver.back() #回退到主页
            (self.driver.find_element(By.CSS_SELECTOR,
            "#sk-layout > div > div > section > aside > div > div:nth-child(1) > ul > li:nth-child(2) > span > a > div > span.anticon.ant-pro-base-menu-item-icon > span > svg")
             .click())  # 点击我的项目
            examnums=self.driver.find_elements(By.CSS_SELECTOR,"span.survey-title")  # 查找
            res=any("不保存的考试"==name.text for name in examnums)
            if res:
                print("不保存的考试——异常存在")
                TestDriver.getScreeShot()
            
            self.driver.fullscreen_window()
            # 2.保存考试后不开启考试 —— 清空标题名,名字设置为保存但不开启的考试,保存,回退两次到主页,再点我的项目,再用find_elemengt选中名字进入
            # 点击网址跳转到新窗口,切换窗口,显示问卷已暂停回收
            # 首页不能点击,只能back
            time.sleep(1)
            self.driver.back()  # 从我的项目回退到首页栏
            (self.driver.find_element(By.CSS_SELECTOR, "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-col.ant-col-xs-24.ant-col-sm-24.ant-col-md-24.ant-col-lg-24.ant-col-xl-8 > div > div.ant-card-body > div > a:nth-child(2)")
             .click())  # 创建考试
            time.sleep(1)
            self.driver.fullscreen_window()
            (self.driver.find_element(By.CSS_SELECTOR,
            "#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor > p")
             .clear())  # 清空考试名称
            (self.driver.find_element(By.CSS_SELECTOR,
            "#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor > p")
             .send_keys("保存但不开启的考试"))  # 设置考试名字
            time.sleep(2)
            (self.driver.find_element(By.CSS_SELECTOR,"#editor > div.survey-main-panel > div.survey-main-panel-toolbar > div:nth-child(2) > div > button.ant-btn.ant-btn-primary.ant-btn-sm > span")
             .click())  # 保存考试 ———— 如果不是全屏就找不到保存元素
            self.driver.back()  # 回退到主页
            self.driver.back()  # 回退到主页
            time.sleep(2)
            (self.driver.find_element(By.CSS_SELECTOR, "#sk-layout > div > div > section > aside > div > div:nth-child(1) > ul > li:nth-child(2) > span > a > div > span.anticon.ant-pro-base-menu-item-icon > span > svg")
             .click())  # 点击我的项目
            time.sleep(1)
            examnums = self.driver.find_elements(By.CSS_SELECTOR, "span.survey-title")  # 查找
            name_element=None
            for name in examnums:
                if name.get_attribute("title")=="保存但不开启的考试":
                    name_element=name
                    break

            if name_element:
                name_element.click()
            else:
                print("保存但不开启的考试——异常不存在")
                TestDriver.getScreeShot() #截图记录

            #不开启考试直接点击打开网址按钮
            self.driver.find_element(By.CSS_SELECTOR,"#root > div > div.survey-main-content > div > div > div:nth-child(2) > div:nth-child(2) > div.ant-row > div > div > div:nth-child(1) > span.ant-input-group-wrapper.ant-input-search.ant-input-search-with-button.open-target > span > span > button > span").click()
            #出现了新窗口,跳转到新窗口
            curwindow=self.driver.current_window_handle #获取当前窗口的句柄
            allwindow=self.driver.window_handles #获取所有窗口句柄
            for window in allwindow:
                if window!=curwindow:
                    self.driver.switch_to.window(window) #切换到新的窗口
                    break
            #对新窗口进行操作
            text=self.driver.find_element(By.CSS_SELECTOR,"#root > div > div > div > h2").text
            if text=="问卷已暂停回收":
                assert (text=="问卷已暂停回收")
                TestDriver.getScreeShot()  # 截图记录
            #关闭新窗口,获取所有窗口句柄,切换回老窗口
            self.driver.close()
            allwindow = self.driver.window_handles  # 获取所有窗口句柄
            for window in allwindow:
                if window:
                    self.driver.switch_to.window(window)
                    break
                else:
                    print("异常,所有窗口已经关闭")
                    TestDriver.getScreeShot()  # 截图记录
            
            time.sleep(1)
            self.driver.fullscreen_window()
            time.sleep(1)
            # 3.保存考试后开启无题目的考试 —— 清空标题名,名字设置为开启但没题目的考试,保存,回退两次到主页,再点我的项目,再用find_elemengt选中名字进入,
            # 点击开启考试,点击网址跳转到新窗口,切换窗口,find_elemengts判断提交按钮不存在
            # 回退两次——从考试设置回退到我的项目——再退到首页
            self.driver.back()  # 从考试开启回退到我的项目
            self.driver.back()  # 从我的项目回退到首页栏
            time.sleep(1)
            (self.driver.find_element(By.CSS_SELECTOR,
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-col.ant-col-xs-24.ant-col-sm-24.ant-col-md-24.ant-col-lg-24.ant-col-xl-8 > div > div.ant-card-body > div > a:nth-child(2)")
             .click())  # 创建考试
            time.sleep(2)
            self.driver.fullscreen_window()
            time.sleep(2)
            (self.driver.find_element(By.CSS_SELECTOR,
            "#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor > p")
             .clear())  # 清空考试名称
            (self.driver.find_element(By.CSS_SELECTOR,
            "#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor > p")
             .send_keys("保存开启但无题目的考试"))  # 设置考试名字
            time.sleep(1)
            (self.driver.find_element(By.CSS_SELECTOR,
            "#editor > div.survey-main-panel > div.survey-main-panel-toolbar > div:nth-child(2) > div > button.ant-btn.ant-btn-primary.ant-btn-sm > span")
             .click())  # 保存考试
            self.driver.back()  # 回退到主页
            self.driver.back()  # 回退到主页
            (self.driver.find_element(By.CSS_SELECTOR,
            "#sk-layout > div > div > section > aside > div > div:nth-child(1) > ul > li:nth-child(2) > span > a > div > span.anticon.ant-pro-base-menu-item-icon > span > svg")
             .click())  # 点击我的项目
            time.sleep(1)
            examnums = self.driver.find_elements(By.CSS_SELECTOR, "span.survey-title")  # 查找
            name_element = None
            for name in examnums:
                if name.get_attribute("title") == "保存开启但无题目的考试":
                    name_element = name
                    break

            if name_element:
                name_element.click()
            else:
                print("保存开启但无题目的考试——异常不存在")
                TestDriver.getScreeShot()  # 截图记录

            # 点击开启考试按钮
            self.driver.find_element(By.CSS_SELECTOR,"#root > div > div.survey-main-content > div > div > div:nth-child(2) > div:nth-child(2) > div.ant-row > div > div > div:nth-child(2) > div:nth-child(2) > button").click()
            # 点击打开网址按钮
            self.driver.find_element(By.CSS_SELECTOR,
            "#root > div > div.survey-main-content > div > div > div:nth-child(2) > div:nth-child(2) > div.ant-row > div > div > div:nth-child(1) > span.ant-input-group-wrapper.ant-input-search.ant-input-search-with-button.open-target > span > span > button > span").click()
            # 出现了新窗口,跳转到新窗口
            curwindow = self.driver.current_window_handle  # 获取当前窗口的句柄
            allwindow = self.driver.window_handles  # 获取所有窗口句柄
            for window in allwindow:
                if window != curwindow:
                    self.driver.switch_to.window(window)  # 切换到新的窗口
                    break
            # 对新窗口进行操作
            # 找提交按钮,目标:按钮不存在
            my_list=self.driver.find_elements(By.CSS_SELECTOR,"#root > div > div > div > div.survey-antd-footer > div.survey-antd-footer-pagination > div > button > div")
            # 找不到返回空列表
            if len(my_list)>0:
                assert (len(my_list)>0) #不是空列表代表出现异常
                TestDriver.getScreeShot()  # 截图记录
            # 关闭新窗口,获取所有窗口句柄,切换回老窗口
            self.driver.close()
            allwindow = self.driver.window_handles  # 获取所有窗口句柄
            for window in allwindow:
                if window:
                    self.driver.switch_to.window(window)
                    break
                else:
                    print("异常,所有窗口已经关闭")
                    TestDriver.getScreeShot()  # 截图记录
        
            self.driver.back()  # 从考试开启回退到我的项目
            self.driver.back()  # 从我的项目回退到首页栏
        finally:
            TestDriver.getScreeShot()  # 截图记录

    def ExamEditCheck(self): # 创建考试的页面检查
        self.driver.fullscreen_window()
        #检查页面元素:标题输入框,题目:题型、大纲。提交、预览、保存
        # 题型
        self.driver.find_element(By.CSS_SELECTOR, "#rc-tabs-0-tab-1")
        # 大纲
        self.driver.find_element(By.CSS_SELECTOR, "#rc-tabs-0-tab-3")
        # 提交
        self.driver.find_element(By.CSS_SELECTOR, "#editorContent > div > div > div.footer > div.title > div > div > pre > div.ql-editor > p")
        # 预览
        self.driver.find_element(By.CSS_SELECTOR, "#editor > div.survey-main-panel > div.survey-main-panel-toolbar > div:nth-child(2) > div > button:nth-child(3) > span")
        # 保存
        self.driver.find_element(By.CSS_SELECTOR, "#editor > div.survey-main-panel > div.survey-main-panel-toolbar > div:nth-child(2) > div > button.ant-btn.ant-btn-primary.ant-btn-sm > span")
        # 添加截图
        TestDriver.getScreeShot()

RunTest

按顺序定义的顺序串联执行各类测试场景,形成从 “注册→登录→创建问卷→执行问卷” 的完整测试链路实现对商城系统核心功能的自动化验证

复用Driver单例浏览器对象,确保所有测试在同一浏览器实例中执行,避免重复初始化
通过finally块保证证测试结束后自动关闭浏览器(driver.quit()),释放资源

from tests  import TestLogin
from tests import TestRegister
from tests import TestHome
from tests import TestEdit
from tests import ExamEdit
from common.Utils import TestDriver

if __name__ == "__main__":
try:
    print("测试开始")
    ExamEdit.ExamEdit().ExamEditNotLogin() # 未登录状态下发布文章
    #TestRegister.TestRegister().RegisterSuccess()
    TestRegister.TestRegister().RegisterFail() # 注册失败
    TestLogin.TestLogin().LoginFail() # 登录失败
    TestHome.TestHome().TestHomeNotLogin()  # 未登录状态下的首页
    TestLogin.TestLogin().LoginSuccess()#登录成功
    TestHome.TestHome().TestHomeByLogin()  #登录状态下的首页
    ExamEdit.ExamEdit().ExamEditCheck() #检查页面元素
    ExamEdit.ExamEdit().ExamNoEditByLogin()  # 登录状态下,异常发布文章失败
    ExamEdit.ExamEdit().ExamYesEditByLogin() # 登录状态下,正常发布文章成功
    print("测试结束")
except:
    print("测试失败")
finally:
    #测试完成后退出浏览器
    TestDriver.driver.quit()

总结

拆分不同业务场景为独立类(Driver驱动类、TestRegister注册类、TestLogin登录类、TestHome首页类、ExamEdit问卷交互类),实现 —— 高内聚、低耦合。通过模块化设计和场景化用例,有效验证了用户从注册到验证考试结果的核心流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值