使用ChatGPT生成登录产品代码的测试用例和测试脚本

简介: 使用ChatGPT生成登录产品代码的测试用例和测试脚本

10.1生成测试用例

10.1.1 申请生成登录测试用例

产品登录页面如下:

代码语言:javascript

复制

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="../css/index.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
   <script src="https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/core.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/sha256.js"></script>
    <title>登录页面</title>
  <script src="../js/index.js" type="text/javascript"></script>
</head>
<body>
<div class="container">
    <h2>登录</h2>
   <form id="loginForm" name="loginForm" method="POST" action="login.jsp" onsubmit="return validateLoginForm();">
   <input type="hidden" id="csrftoken" name="csrftoken" value="vRB6kNVanUDbT8g5b1bMY3fx6eoHXJhHiStsDc8EyAdTx2BkHrFCIXavHSA2ss6u6eZUMYLvH4pJmxCAGcpWWUguwme7AXy6NkTk">
            <div>
                <label for="username">用户名:</label>
                <input type="text" id="username" name="username" placeholder="输入账号" required>
                <div id="usernameError" class="error"></div>
            </div>
            <div>
                <label for="password">密码:</label>
                <input type="password" id="password" name="password" placeholder="输入密码" required>
                <div id="passwordError" class="error"></div>
            </div>
            <button type="submit">登录</button>
    </form>
  <div id="loginError" class="error">
    </div>
  </div>
</body>
</html>

登录页面界面包括。

l账号:文本框,5-20位大小写英文字符、数字。重复的账户不允许注册

l密码:密码框,必须包括大小写英文字符、数字和特殊字符,5-30位,SHA256散列传输。

登录成功出现“登录XXXX系统”提示。

登录失败,出现“用户名或密码错误“。

避免XSS注入

避免CSRF注入

避免SQL注入

不登录,直接在浏览器地址栏粘贴登录后地址,返回登录页面。

请设计测试用例。

10.1.2 生成登录测试用例回复

以下是针对产品登录页面的测试用例设计,涵盖了功能性、边界情况和安全性等方面的测试:

测试用例设计

1)功能性测试

用例ID

测试内容

输入数据

预期结果

TC-001

验证有效用户名和密码登录

用户名: validUser

登录成功,显示“登录XXXX系统”提示

TC-002

验证无效用户名登录

用户名: invalidUser

显示“用户名或密码错误”

TC-003

验证无效密码登录

用户名: validUser, 密码: wrongPassword

显示“用户名或密码错误”

TC-004

验证空用户名登录

用户名: ""密码: validPassword

显示“用户名或密码错误”

TC-005

验证空密码登录

用户名: validUser密码: ""

显示“用户名或密码错误”

TC-006

验证用户名长度边界

用户名: "a"(1个字符)

显示“用户名长度不符合要求”

TC-007

验证密码长度边界

密码: "123"(3个字符)

显示“密码长度不符合要求”

2)边界情况测试

用例ID

测试内容

输入数据

预期结果

TC-008

验证用户名最大长度

用户名: "validUser123456789012345"

登录成功,显示“登录XXXX系统”提示

TC-009

验证用户名最小长度

用户名: "user"

登录成功,显示“登录XXXX系统”提示

TC-010

验证密码最大长度

密码: "ValidPassword123!"(30个字符)

登录成功,显示“登录XXXX系统”提示

TC-011

验证密码最小长度

密码: "P@ss1"

登录成功,显示“登录XXXX系统”提示

3)安全性测试

用例ID

测试内容

输入数据

预期结果

TC-012

验证XSS注入

用户名: " <> alert('XSS') "

显示“用户名或密码错误”

TC-013

验证CSRF保护

模拟CSRF攻击

登录失败,显示“用户名或密码错误”

TC-014

验证SQL注入

用户名: "admin' --"

显示“用户名或密码错误”

4)重定向测试

用例ID

测试内容

输入数据

预期结果

TC-015

验证未登录用户访问登录后地址

直接访问: "/dashboard"

重定向回登录页面

备注

测试用例中涉及的“有效用户名”和“有效密码”需要根据系统的实际注册情况进行定义。

安全性测试用例需要在安全测试环境中进行,以避免对生产环境造成影响。

测试用例的执行结果应记录实际结果与预期结果的对比,确保功能的正确性和安全性。

10.1.3 更新测试用例

假设存在一个账户,用户名:validUser,密码:ValidPassword123!。

1)功能性测试

用例ID

测试内容

输入数据

预期结果

TC-001

验证有效用户名和密码登录

用户名: validUser密码:ValidPassword123!

登录成功,显示“登录XXXX系统”提示

TC-002

验证无效用户名登录

用户名: invalidUser密码:ValidPassword123!

显示“用户名或密码错误”

TC-003

验证无效密码登录

用户名: validUser, 密码: wrongPassword

显示“用户名或密码错误”

TC-004

验证空用户名登录

用户名: ""密码: validPassword

显示“账号必须是5-20位字母或数字”

TC-005

验证空密码登录

用户名: validUser密码: ""

显示“用户名或密码错误”

TC-006

验证用户名长度边界

用户名: "a"(1个字符)

显示“账号必须是5-20位字母或数字”

TC-007

验证密码长度边界

密码: "123"(3个字符)

显示“密码必须包含大小写字母、数字和特殊字符,长度在5-30之间”

TC-001、TC-002、TC-003、TC-004、TC-005、TC-005:用API测试用例实现。

TC-006、TC-007:用GUI测试用例实现。

2)边界情况测试

用例ID

测试内容

输入数据

预期结果

TC-008

验证用户名最大长度

用户名: "validUser12345678900"

登录成功,显示“登录XXXX系统”提示

TC-009

验证用户名最小长度

用户名: "user1"

登录成功,显示“登录XXXX系统”提示

TC-010

验证密码最大长度

密码: "ValidPassword1234567890123456!"(30个字符)

登录成功,显示“登录XXXX系统”提示

TC-011

验证密码最小长度

密码: "P@ss1"

登录成功,显示“登录XXXX系统”提示

所以测试用例均用API测试用例实现。

3)安全性测试

用例ID

测试内容

输入数据

预期结果

TC-012

验证XSS注入

用户名: " <> alert('XSS') "

显示“账号必须是5-20位字母或数字”

TC-013

验证CSRF保护

模拟CSRF攻击

登录失败,显示“ ”

TC-014

验证SQL注入

用户名: "admin' --"

显示“账号必须是5-20位字母或数字”

所以测试用例均用API测试用例实现。

4)重定向测试

用例ID

测试内容

输入数据

预期结果

TC-015

验证未登录用户访问登录后地址

登录,然后登出,直接访问: "/welcome.jsp"

重定向回登录页面

所以测试用例均用GUI测试用例实现。

10.2 生成登录API测试用例

10.2.1 申请登录API测试用例

生成如下的基于Python requests类+unittest框架的API测试用例脚本。

TC-001,验证有效用户名和密码登录,用户名: validUser,密码:ValidPassword123!,登录成功,显示“登录XXXX系统”提示。

TC-002,验证无效用户名登录,用户名: invalidUser,密码:ValidPassword123!,显示“用户名或密码错误”。

TC-003,验证无效密码登录,用户名: validUser, 密码: wrongPassword,显示“用户名或密码错误”。

TC-004,验证空用户名登录,用户名: "",密码: validPassword ,显示“账号必须是5-20位字母或数字”。

TC-005,验证空密码登录,用户名: validUser,密码: "",显示“密码应该哈希进行存储”。

TC-008,验证用户名最大长度,用户名: "validUser123456789012345",登录成功,显示“登录XXXX系统”提示。

TC-009,验证用户名最小长度,用户名: "user1",登录成功,显示“登录XXXX系统”提示。

TC-010,验证密码最大长度,密码: "ValidPassword1234567890123456!"(30个字符),登录成功,显示“登录XXXX系统”提示。

TC-011,验证密码最小长度,密码: "P@ss1",登录成功,显示“登录XXXX系统”提示。

TC-012,验证XSS注入,用户名: "    <>      alert('XSS')      " ,显示“用户名或密码错误”。

TC-013,验证CSRF保护,模拟CSRF攻击,登录失败,显示“用户名或密码错误”。

TC-014,验证SQL注入,用户名: "admin' --" ,显示“用户名或密码错误”。

10.2.2登录API测试用例回复

下面是一个基于Python requests 类和 unittest 框架的API测试用例脚本,涵盖您提供的所有测试用例。请确保在运行此脚本之前,您已安装了 requests 库,并将相应的URL和响应内容替换为您实际使用的API。

代码语言:javascript

复制

import requests
import unittest
 
# 基础URL
BASE_URL = "http://your-api-url.com/login"  # 替换为实际的登录API URL
WELCOME_URL = "http://your-api-url.com/welcome.jsp"  # 替换为实际的受保护页面URL
 
class TestLoginAPI(unittest.TestCase):
 
    def test_valid_login(self):
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "登录XXXX系统")
 
    def test_invalid_username(self):
        response = requests.post(BASE_URL, data={'username': "invalidUser", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "用户名或密码错误")
 
    def test_invalid_password(self):
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': "wrongPassword"})
        self.assertEqual(response.json().get('message'), "用户名或密码错误")
 
    def test_empty_username(self):
        response = requests.post(BASE_URL, data={'username': "", 'password': "validPassword"})
        self.assertEqual(response.json().get('message'), "账号必须是5-20位字母或数字")
 
    def test_empty_password(self):
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': ""})
        self.assertEqual(response.json().get('message'), "密码应该哈希进行存储")
 
    def test_username_max_length(self):
        response = requests.post(BASE_URL, data={'username': "validUser123456789012345", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "登录XXXX系统")
 
    def test_username_min_length(self):
        response = requests.post(BASE_URL, data={'username': "user1", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "登录XXXX系统")
 
    def test_password_max_length(self):
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': "ValidPassword1234567890123456!"})
        self.assertEqual(response.json().get('message'), "登录XXXX系统")
 
    def test_password_min_length(self):
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': "P@ss1"})
        self.assertEqual(response.json().get('message'), "登录XXXX系统")
 
    def test_xss_injection(self):
        response = requests.post(BASE_URL, data={'username': "    <>      alert('XSS')      ", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "用户名或密码错误")
 
    def test_csrf_protection(self):
        # 假设CSRF令牌是必需的,这里我们不提供CSRF令牌
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "用户名或密码错误")
 
    def test_sql_injection(self):
        response = requests.post(BASE_URL, data={'username': "admin' --", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "用户名或密码错误")
 
if __name__ == "__main__":
    unittest.main()

10.2.3调整登录API测试程序

1)修改Util.py

代码语言:javascript

复制

import pymysql
import re
import hashlib
 
class ClassDB:
    #初始化数据库连接
    def initDB(self):
        host = 'localhost'
        user = 'root'
        password = '123456'
        database = 'ebusiness'
        # 创建数据库连接
        connection = pymysql.connect(host=host, user=user, password=password, database=database)
        return connection
        
    # 关闭数据库连接
    def closedb(self,connection):
        connection.close()
 
    # 清空数据库user表中数据,用于DearDown
    def init_db(self):
        connection = self.initDB()
        try:
            with connection.cursor() as cursor:
                # SQL语句,用于清空user表
                sql = "TRUNCATE TABLE user"    
                # 执行SQL语句
                cursor.execute(sql)   
                # 提交事务
                connection.commit()
        finally:
            self.closedb(connection)
 
    #为登录初始化数据
    def init_login(self):
        connection = self.initDB()
        try:
            with connection.cursor() as cursor:
                password = HASH.hash_password("ValidPassword123!")
                # SQL语句,用于清空user表
                sql = "INSERT INTO user (username, password, phone, email) VALUES (\"validUser\",\""+password+"\", \"13611223344\", \"a@b.com\")"  
                # 执行SQL语句
                cursor.execute(sql)       
                # 提交事务
                connection.commit()
        finally:
            self.closedb(connection)
 
    #建立特定用户名的user数据,密码为默认“ValidPassword123!”
    def login_for_name(self,username):
        connection = self.initDB()
        try:
            with connection.cursor() as cursor:
                password = HASH.hash_password("ValidPassword123!")
                # SQL语句,用于清空user表
                sql = "INSERT INTO user (username, password, phone, email) VALUES (\""+username+"\",\""+password+"\", \"13611223344\", \"a@b.com\")"      
                # 执行SQL语句
                cursor.execute(sql)      
                # 提交事务
                connection.commit()
        finally:
            self.closedb(connection)
 
    #建立特定密码的user数据,用户名为默认“validUser”
    def login_for_password(self,password):
        connection = self.initDB()
        try:
            with connection.cursor() as cursor:
                password = HASH.hash_password(password)
                # SQL语句,用于清空user表
                sql = "INSERT INTO user (username, password, phone, email) VALUES (\"validUser\",\""+password+"\", \"13611223344\", \"a@b.com\")"      
                # 执行SQL语句
                cursor.execute(sql)      
                # 提交事务
                connection.commit()
        finally:
            self.closedb(connection)
        
        
        
class CSRF:
    def get_csrf(html):
        pattern = r'input[^>]+value="([^"]+)"'
        # 使用 re.search 查找匹配
        match = re.search(pattern, html)
        # 提取并打印 value 值
        if match:
            csrftoken_value = match.group(1)
            return csrftoken_value
        else:
            return "未找到 csrftoken"
 
class HASH:
    #对字符串仅更新SHA256散列
    def hash_password(password):
        """对密码进行SHA256散列"""
        return hashlib.sha256(password.encode('utf-8')).hexdigest()

2)修改TestEbusiness.py为Test_Register.py

代码语言:javascript

复制

from Util import ClassDB
from Util import CSRF
from Util import HASH
 
class TestUserRegistration(unittest.TestCase):
       # 注册接口的URL
       def setUp(self):
              self.REGISTER_URL = "http://127.0.0.1:8080/CharGPTEbusiness/jsp/register.jsp"
              self.session = requests.Session()
              response = self.session.get(self.REGISTER_URL)
              self.csrf = CSRF.get_csrf(response.text)
              self.token={"csrftoken":self.csrf}
              
       def tearDown(self):
              self.db = ClassDB()
              self.db.init_db()
3) 修改Test_register_GUI.py
from Util import ClassDB
import time
 
REGISTER_URL = 'http://127.0.0.1:8080/CharGPTEbusiness/jsp/register.jsp'
# 测试类
class TestUserRegistration:   
    def teardown_class(self):
           self.db = ClassDB()
           self.db.init_db()
4)建立Test_Login.py
import requests
import unittest
from Util import ClassDB
from Util import CSRF
from Util import HASH
 
# 基础URL
BASE_URL = "http://127.0.0.1:8080/CharGPTEbusiness/jsp/login.jsp"  # 替换为实际的登录API URL
WELCOME_URL = "http://127.0.0.1:8080/CharGPTEbusiness/jsp//welcome.jsp"  # 替换为实际的受保护页面URL
 
class TestLoginAPI(unittest.TestCase):
    def setUp(self):
        self.session = requests.Session()
        response = self.session.get(BASE_URL)
        self.csrf = CSRF.get_csrf(response.text)
        self.token={"csrftoken":self.csrf}
        self.db = ClassDB()
        self.db.init_login()
              
    def tearDown(self):
        self.db.init_db()
       
    def test_valid_login(self):
        """TC-001:验证有效用户名和密码登录"""
        self.token['username'] = "validUser"
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser",
           'password': HASH.hash_password("ValidPassword123!")
       },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("系统欢迎您", response.text)
    
def test_invalid_username(self):
        """TC-002:验证无效用户名登录"""
        self.token['username'] = "invalidUser"
        response = requests.post(BASE_URL,
       data={
           'csrftoken':self.csrf,
           'username': "invalidUser",
           'password': HASH.hash_password("ValidPassword123!")
       },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("用户名或密码错误", response.text)
 
    def test_invalid_password(self):
        """TC-003,验证无效密码登录"""
        self.token['username'] = "validUser"
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser",
           'password': HASH.hash_password("wrongPassword")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("用户名或密码错误", response.text)
 
    def test_empty_username(self):
        """TC-004,验证空用户名登录"""
        self.token['username'] = ""
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "",
           'password':HASH. hash_password("validPassword")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("     ", response.text)
 
    def test_empty_password(self):
        """TC-005,验证空密码登录"""
        self.token['username'] = "validUser"
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser",
           'password': HASH.hash_password("")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("用户名或密码错误", response.text)
 
    def test_username_max_length(self):
        """TC-008,验证用户名最大长度"""
        self.token['username'] = "validUser12345678900"
        self.db.login_for_name("validUser12345678900")
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser12345678900",
           'password': HASH.hash_password("ValidPassword123!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("系统欢迎您", response.text)
    
    def test_username_min_length(self):
        """TC-009,验证用户名最小长度"""
        self.token['username'] =  "user1"
        self.db.login_for_name("user1")
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "user1",
           'password':HASH.hash_password("ValidPassword123!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("欢迎", response.text)
        self.assertIn("登录", response.text)
        self.assertIn("系统", response.text)
 
    def test_password_max_length(self):
        """TC-010,验证密码最大长度"""
        self.token['username'] = "validUser"
        self.db.login_for_password("ValidPassword1234567890123456!")
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser",
           'password': HASH.hash_password("ValidPassword1234567890123456!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("系统欢迎您", response.text)
 
    def test_password_min_length(self):
        """TC-011,验证密码最小长度"""
        self.token['username'] = "validUser"
        self.db.login_for_password("P@ss1")
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser",
           'password': HASH.hash_password("P@ss1")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("系统欢迎您", response.text)
 
    def test_xss_injection(self):
        """TC-012,验证XSS注入"""
        self.token['username'] = "    <>      alert('XSS')      "
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
            'username': "    <>      alert('XSS1')      ",
           'password': HASH.hash_password("ValidPassword123!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("账号必须是5-20位字母或数字", response.text)
 
    def test_csrf_protection(self):
        """TC-013,验证CSRF保护"""
       # 假设CSRF令牌是必需的,这里我们不提供CSRF令牌
        self.token['username'] = "validUser"
        response = requests.post(BASE_URL, data={
           'username': "validUser",
           'password': HASH.hash_password("ValidPassword123!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("     ", response.text)
 
    def test_sql_injection(self):
        """TC-014,验证SQL注入"""
        self.token['username'] = "admin' --"
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "admin' --",
           'password': HASH.hash_password("ValidPassword123!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("账号必须是5-20位字母或数字", response.text)
 
if __name__ == "__main__":
       unittest.main()
10.3 生成登录GUI测试用例
10.3.1 申请生成登录GUI测试用例
对下面用例书写基于playwright+pytest的测试脚本。

前端代码

代码语言:javascript

复制

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="../css/index.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
   <script src="https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/core.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/sha256.js"></script>
    <title>登录页面</title>
  <script src="../js/index.js" type="text/javascript"></script>
</head>
<body>
<div class="container">
    <h2>登录</h2>
   <form id="loginForm" name="loginForm" method="POST" action="login.jsp" onsubmit="return validateLoginForm();">
   <input type="hidden" id="csrftoken" name="csrftoken" value="yDhOJU4vOCv6qSENtpba8xaURQlQlpGQ9W4hJekAt45dLi9ByMEs2DOzaLwtjeo2P4b1pV0crpDqxQo1F3w23blijWE1OBsj99ke">
            <div>
                <label for="username">用户名:</label>
                <input type="text" id="username" name="username" placeholder="输入账号" required>
                <div id="usernameError" class="error"></div>
            </div>
            <div>
                <label for="password">密码:</label>
                <input type="password" id="password" name="password" placeholder="输入密码" required>
                <div id="passwordError" class="error"></div>
            </div>
            <button type="submit">登录</button>
    </form>
  <div id="loginError" class="error">
    </div>
  </div>
</body>
</html>

对下面用例实现基于GUI的测试用例

TC-001 验证有效用户名和密码登录,用户名: validUser,登录成功,显示“登录XXXX系统”提示。

TC-002 验证无效用户名登录,用户名: invalidUser,显示“用户名或密码错误”。

TC-006 验证用户名长度边界,用户名: "a"(1个字符),显示“账号必须是5-20位字母或数字”。

TC-007 验证密码长度边界,密码: "123"(3个字符),显示“密码必须包含大小写字母、数字和特殊字符,长度在5-30之间”。

TC-015 验证未登录用户访问登录后地址,登录,然后登出,直接访问: "/welcome.jsp"重定向回登录页面。

假设存在一个账户,用户名:validUser,密码:ValidPassword123!。

10.3.2 生成登录GUI测试用例回复

下面是基于Playwright和pytest的测试脚本实现,涵盖了您提供的用例。请确保您已经安装了Playwright和pytest,并且已正确配置了测试环境。

首先,您需要在项目目录中创建一个新的Python文件,比如test_login.py,然后将以下代码粘贴到该文件中:

代码语言:javascript

复制

import pytest
from playwright.sync_api import sync_playwright
 
# 测试用例
@pytest.mark.parametrize("username, password, expected_message", [
    ("validUser", "ValidPassword123!", "登录XXXX系统"),  # TC-001
    ("invalidUser", "ValidPassword123!", "用户名或密码错误"),  # TC-002
    ("a", "ValidPassword123!", "账号必须是5-20位字母或数字"),  # TC-006
    ("validUser", "123", "密码必须包含大小写字母、数字和特殊字符,长度在5-30之间"),  # TC-007
])
def test_login(username, password, expected_message):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        page.goto("file://path/to/your/html/file.html")  # 替换为您的HTML文件路径
 
        # 填充用户名和密码
        page.fill("#username", username)
        page.fill("#password", password)
        # 提交表单
        page.click("button[type='submit']")
        
        # 等待页面加载并验证消息
        page.wait_for_selector("#loginError, h2")  # 等待登录错误或成功消息
        
        if expected_message == "登录XXXX系统":
            assert page.locator("h2").inner_text() == expected_message
        else:
            assert page.locator("#loginError").inner_text() == expected_message
        
        browser.close()
 
def test_access_protected_page_after_logout():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        
        # 登录
        page.goto("file://path/to/your/html/file.html")  # 替换为您的HTML文件路径
        page.fill("#username", "validUser")
        page.fill("#password", "ValidPassword123!")
        page.click("button[type='submit']")
        
        # 退出登录
        # 假设有一个退出登录的按钮,您需要根据实际情况进行调整
        page.click("#logoutButton")  # 替换为实际的注销按钮选择器
        
        # 尝试访问受保护的页面
        page.goto("file:///path/to/welcome.jsp")  # 替换为欢迎页面的真实路径
        
        # 验证重定向回登录页面
        assert page.url == "file://path/to/your/html/file.html"  # 替换为登录页面的真实路径
        
        browser.close()

说明

测试用例: 使用@pytest.mark.parametrize装饰器来定义多个测试用例,涵盖有效和无效的用户名和密码。

浏览器操作: 使用Playwright的API来启动浏览器、打开页面、填写表单、提交表单并验证结果。

重定向测试: test_access_protected_page_after_logout函数用于测试未登录用户访问受保护页面的情况。

路径替换: 请确保将file://path/to/your/html/file.html和file:///path/to/welcome.jsp替换为您本地的实际文件路径。

运行测试

确保您已安装pytest和Playwright。您可以通过以下命令运行测试:

代码语言:javascript

复制

pytest test_login.py

请根据您的具体需求和环境进行调整。

10.3.3调整登录GUI测试程序

代码语言:javascript

复制

import pytest
from playwright.sync_api import Page
from Util import ClassDB
import time
 
LOGIN_URL = 'http://127.0.0.1:8080/CharGPTEbusiness/jsp/login.jsp'
WELCOME_URL ='http://127.0.0.1:8080/CharGPTEbusiness/jsp/welcome.jsp'
# 测试类
class TestUserLogin:
    def setup_class(self):
        self.db = ClassDB()
        self.db.init_login()
 
    def teardown_class(self):
        self.db.init_db()
 
    # 测试用例
    @pytest.mark.parametrize("username, password, expected_message", [
        ("validUser", "ValidPassword123!", "系统欢迎您"),  # TC-001
        ("invalidUser", "ValidPassword123!", "用户名或密码错误"),  # TC-002
        ("a", "ValidPassword123!", "账号必须是5-20位的字母或数字"),  # TC-006
        ("validUser", "123", "密码必须包含大小写字母、数字和特殊字符,长度在5-30之间"),  # TC-007
 
    ])
    def test_login(self,page: Page,username, password, expected_message):
        page.goto(LOGIN_URL)
        page.reload()
 
        # 填充用户名和密码
        page.fill("#username", username)
        page.fill("#password", password)
        page.click("button[type='submit']")
        
        # 等待页面加载并验证消息
        if expected_message == "系统欢迎您":
            page.wait_for_selector("h1")  # 等待成功消息
        else:
            page.wait_for_selector("h2")  # 等待登录错误
        
        if username == "validUser":
            if password != "123":
                assert page.locator("h1").inner_text() == expected_message
            else:
                assert expected_message in page.locator("#passwordError").inner_text()            
        elif username == "invalidUser":
            assert expected_message in page.locator("#loginError").inner_text()
        elif username == "a":
            assert expected_message in page.locator("#usernameError").inner_text()
        else:
                assert 0==1
    def test_access_protected_page_after_logout(self,page: Page):       
        # 登录
        page.goto(LOGIN_URL)
        page.reload()
        page.fill("#username", "validUser")
        page.fill("#password", "ValidPassword123!")
        page.click("button[type='submit']")
        page.wait_for_selector("h1")  # 等待成功消息
        page.click("body > a")  # 替换为实际的注销按钮选择器
        
        # 尝试访问受保护的页面
        page.goto(WELCOME_URL)  # 替换为欢迎页面的真实路径
        # 验证重定向回登录页面
        assert page.url == LOGIN_URL  # 替换为登录页面的真实路径
 
if __name__ == '__main__':
pytest.main(["-sv", "Test_login_GUI.py"])

在这里注意

代码语言:javascript

复制

由于expected_messagez在页面中不同的地方出现,所以调整代码:
if username == "validUser":
      if password != "123":
          assert page.locator("h1").inner_text() == expected_message
      else:
          assert expected_message in page.locator("#passwordError").inner_text()            
elif username == "invalidUser":
      assert expected_message in page.locator("#loginError").inner_text()
elif username == "a":
      assert expected_message in page.locator("#usernameError").inner_text()
else:
      assert 0==1

另外在运行过程中发现:

代码语言:javascript

复制

page.fill("#username", "…")
page.fill("#password", "…")
page.click("button[type='submit']")

经常等待不到,后来通过playwright的录制功能,换了

代码语言:javascript

复制

page.get_by_placeholder("输入账号").fill("validUser")
page.get_by_placeholder("输入密码").fill("ValidPassword123!")
page.get_by_role("button", name="登录").click()

就没有问题了。

注意:在使用ChatGPT辅助开发代码的时候,注意结合其他工具一起使用

另外在运行过程中发现每次密码没有执行散列就传输了,后来发现前端代码    

代码语言:javascript

复制

< src="https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/sha256.js">

由于网速很慢,https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/sha256.js无法加载到。把core.js、crypto-js.min.jsh和sha256.js放在项目js目录下。register.jsp和login.js改为:

代码语言:javascript

复制

< src="../js/crypto-js.min.js">     
    < src="../js/core.js">     
    < src="../js/sha256.js">

10.3.4调整注册GUI测试程序

根据登录GUI测试程序调整注册GUI测试。使用pytest.mark.parametrizec参数模式。

注意:ChatGPT每次给出的格式不一致,需要根据经验使用最好的程序

代码语言:javascript

复制

import pytest
from playwright.sync_api import Page
from Util import ClassDB
import time
 
REGISTER_URL = 'http://127.0.0.1:8080/CharGPTEbusiness/jsp/register.jsp'
# 测试类
class TestUserRegistration:   
    def teardown(self):
           self.db = ClassDB()
           self.db.init_db()
        
    # 测试用例
    @pytest.mark.parametrize("username, password, repassword, phone, email, expected_message", [
        ("validUser123", "ValidPass123!", "ValidPass123!","13800138000","test@example.com","登录"),  #GTC1-账号有效性测试
       ("testUser", "Aa1@", "Aa1@","13800138000","test@example.com","密码必须包含大小写字母、数字和特殊字符,长度在5-30之间"),  #GTC2 - 密码长度不足测试
       ("testUser", "iLongpassword12@Longpassword12@", "iLongpassword12@Longpassword12@","13800138000","test@example.com","密码必须包含大小写字母、数字和特殊字符,长度在5-30之间"),  #GTC3 - 密码长度超出测试
       ("testUser", "ValidPass123!", "validPass123!","13800138000","test@example.com","密码确认不一致"),  #GTC4 - 输入密码与确认密码确保不一致性
       ("testUser", "ValidPass123!", "ValidPass123!","12345","test@example.com","请输入有效的中国手机号"),  ##GTC5 - 手机号格式错误测试
    ])
    def test_Login(self,page: Page,username, password, repassword, phone, email, expected_message):
        page.goto(REGISTER_URL)
        page.reload()
        page.fill('input[name="username"]', username)
        page.fill('input[name="password"]', password)
        page.fill('input[name="confirmPassword"]', repassword)
        page.fill('input[name="phone"]',  phone)
        page.fill('input[name="email"]', email)
        page.click('button[type="submit"]')
        # 检查注册是否成功(这里需要根据实际页面反馈调整)
        if expected_message == "登录":
            assert page.get_by_role("heading", name="登录")
        else:
            assert page.locator('text='+expected_message).is_visible()
      
 
    # 测试用例
    @pytest.mark.parametrize("username, password, repassword, phone, email, username_1,phone_1,email_1,expected_message", [
        ("duplicateUser", "ValidPass123!", "ValidPass123!","13800138000","duplicate@example.com","duplicateUser","13800138001","duplicate2@example.com","注册用户的用户名必须唯一"),  #GTC6 – 一个用户重复注册两次。
       ("duplicateUser3", "ValidPass123!", "ValidPass123!","13800138003","duplicate1@example.com","duplicateUser4","13800138003","duplicate1@example.com","注册用户的手机必须唯一"),  #GTC7 – – 不同用户注册,手机号重复
       ("duplicateUser1", "ValidPass123!", "ValidPass123!","13800138004","duplicate3@example.com","duplicateUser4","13800138005","duplicate3@example.com","注册用户的邮箱必须唯一"), #GTC8 – 不同用户注册,邮件重复
    ])
    def test_duplicate(self,page: Page,username, password, repassword, phone, email, username_1,phone_1,email_1,expected_message):
        page.goto(REGISTER_URL)
        page.reload()
        # 第一次注册
        page.fill('input[name="username"]', username)
        page.fill('input[name="password"]', password)
        page.fill('input[name="confirmPassword"]', repassword)
        page.fill('input[name="phone"]', phone)
        page.fill('input[name="email"]', email)
        page.click('button[type="submit"]')
        # 检查注册成功
        assert page.get_by_role("heading", name="登录")
        # 第二次注册相同用户
        page.goto(REGISTER_URL)
        page.reload()
        page.fill('input[name="username"]', username_1)
        page.fill('input[name="password"]', password)
        page.fill('input[name="confirmPassword"]', repassword)
        page.fill('input[name="phone"]', phone_1)
        page.fill('input[name="email"]', email_1)
        page.click('button[type="submit"]')
        # 检查错误信息
        print(expected_message)
        assert page.locator('text='+expected_message).is_visible()
 
if __name__ == '__main__':
    pytest.main(["-sv", "Test_register_GUI.py"])

10.4 总结

共有以下测试用例,其中API测试用例12个,分别如下:

TC-001 验证有效用户名和密码登录

TC-002 验证无效用户名登录

TC-003 验证无效密码登录

TC-004 验证空用户名登录

TC-005 验证空密码登录

TC-008 验证用户名最大长度

TC-009 验证用户名最小长度

TC-010 验证密码最大长度

TC-011 验证密码最小长度

TC-012 验证XSS注入

TC-013 验证CSRF保护

TC-014 验证SQL注入

GUI测试用例5个,分别如下:

TC-001 验证有效用户名和密码登录

TC-002 验证无效用户名登录

TC-006 验证用户名长度边界

TC-007 验证密码长度边界

TC-015 验证未登录用户访问登录后地址

没有手工测试用例。

目录
相关文章
|
20天前
|
前端开发 JavaScript Java
使用ChatGPT生成登录产品代码
使用ChatGPT生成登录产品代码
65 33
|
20天前
|
前端开发 JavaScript Java
通过ChatGPT生成测试用例和测试脚本(2)
通过ChatGPT生成测试用例和测试脚本
61 21
|
20天前
|
JavaScript 前端开发 Java
使用ChatGPT生成关于登录产品代码的单元测试代码
使用ChatGPT生成关于登录产品代码的单元测试代码
41 16
|
20天前
|
前端开发 JavaScript Java
使用ChatGPT关于登录产品代码的代码评审
整体来看,您的测试代码结构清晰,覆盖面广,关注了安全性测试。通过一些小的改进,可以提高代码的可维护性和安全性。继续保持良好的测试习惯,并考虑使用一些现代化的工具和库来简化测试工作。
38 13
|
1月前
|
机器学习/深度学习 人工智能 搜索推荐
哈佛推出全新类ChatGPT癌症诊断AI,登上Nature!准确率高达96%
哈佛大学研究团队开发的新型AI模型CHIEF,在《自然》期刊发表,癌症诊断准确率达96%。CHIEF基于深度学习,能自动识别、分类癌症并预测生存期,具高准确性、多任务能力和泛化性。它结合病理图像与基因组学等数据,显著提升诊断效率和个性化治疗水平,有望改善医疗资源不平等。但数据隐私和临床效果验证仍是挑战。论文见:https://www.nature.com/articles/s41586-024-07894-z
169 101
|
1天前
|
存储 人工智能 API
ChatGPT-on-WeChat:Star32.4k, DeepSeek加持!这款开源神器秒变AI助手,聊天体验直接起飞!
嗨,大家好,我是小华同学。今天为大家介绍一款结合DeepSeek引擎的开源项目——ChatGPT-on-WeChat,由开发者zhayujie打造。它将微信变成智能AI助手,支持文本、图片、语音对话,具备定时提醒、天气查询等扩展功能,完全开源且易于定制。项目地址:https://github.com/zhayujie/chatgpt-on-wechat。关注我们,获取更多优质开源项目和高效学习方法。
55 11
|
3天前
|
人工智能 自然语言处理 算法
DeepSeek vs ChatGPT:AI对决中的赢家是……人类吗?
DeepSeek VS ChatGPT:DeepSeek以开源黑马姿态崛起,凭借低成本、高性能的「DeepSeek-V3」和专为深度推理设计的「DeepSeek-R1」,成为中小开发者的首选。而ChatGPT则较贵。 然而,AI依赖也带来隐忧,长期使用可能导致记忆衰退和“脑雾”现象。为此,推荐Neuriva解决方案,专注力提升30%,记忆留存率提升2.1倍,助力人类在AI时代保持脑力巅峰。 DeepSeek赢在技术普惠,ChatGPT胜于生态构建,人类的关键在于平衡AI与脑力健康,实现“双核驱动”突破极限!
106 7
|
2月前
|
人工智能 搜索推荐 iOS开发
OpenAI推出适用于iPhone的ChatGPT,与Apple实现具有里程碑意义的AI整合
OpenAI推出适用于iPhone的ChatGPT,与Apple实现具有里程碑意义的AI整合
|
6月前
|
人工智能 自然语言处理 搜索推荐
chatgpt这么火,现在AI搜索引擎有哪些呢?
国外AI搜索引擎包括ChatGPT,擅长自然语言处理与内容生成;Google Bard,提供智能个性化搜索体验;Microsoft Bing集成GPT模型增强智能检索;Perplexity AI以简洁答案及文献引用著称;Neeva强调隐私保护与无广告服务。国内方面,天工AI支持多种功能如知识问答与代码编程;腾讯元宝基于混元模型助力内容创造与学习;360AI搜索以精准全面的信息搜索见长;秘塔AI专注提升写作质量和效率;开搜AI搜索提供个性化智能搜索服务。以上引擎均利用先进AI技术提升用户体验。更多详情参阅[AI搜索合集](zhangfeidezhu.com/?page_id=651)。
178 8
chatgpt这么火,现在AI搜索引擎有哪些呢?
|
6月前
|
机器学习/深度学习 人工智能 自然语言处理
HuggingGPT解析:使用 ChatGPT及HuggingFace上的族系解决AI问题
HuggingGPT是一个框架,它使用大型语言模型(如ChatGPT)作为控制器来管理和协调Hugging Face上的AI模型,以语言作为通用接口解决多模态和领域的复杂AI任务。
114 0
HuggingGPT解析:使用 ChatGPT及HuggingFace上的族系解决AI问题