西安网站开发培训多少钱,网站设置保存登录密码怎么取消,免费获取资源的公众号,做网站的销售文章目录 一、功能测试1.编写测试用例2.总结测试后发现的BUG 二、UI自动化测试0.搭建测试环境1. 创建公共类2.注册页面UI自动化测试用例编写3.登录页面UI自动化测试用例编写4.用户博客列表页面自动化测试5. 修改个信息页面6. 文章编辑页面7. 设置密保问题发现bug 8. 所有用户文… 文章目录 一、功能测试1.编写测试用例2.总结测试后发现的BUG 二、UI自动化测试0.搭建测试环境1. 创建公共类2.注册页面UI自动化测试用例编写3.登录页面UI自动化测试用例编写4.用户博客列表页面自动化测试5. 修改个信息页面6. 文章编辑页面7. 设置密保问题发现bug 8. 所有用户文章列表页9. 总结 三、性能测试1.编写性能测试脚本设置参数化 2.创建测试场景3.开始执行简单分析性能测试报告运行的虚拟用户图表点击率表吞吐量表平均事务响应时间图系统资源图表 一、功能测试
1.编写测试用例 2.总结测试后发现的BUG
通过一系列的测试发现项目的以下bug
上传图片功能 上传图片格式不正确直接跳转而没有提示且图片格式校验不严谨发布博客测试 文章正文为空没有提示文章内容为空修改文章 在修改文章时点击保存草稿没有做校验提示错误修改密码 原密码错误提示有问题找回密码 未提示验证码错误新密码格式为空博客列表页 未简略显示文章正文字数过多问题
二、UI自动化测试
0.搭建测试环境
使用Junit5selenium对项目进行简单的自动化测试。
引入Junit5和selenium依赖
dependencygroupIdorg.junit.jupiter/groupIdartifactIdjunit-jupiter/artifactIdversion5.8.2/versionscopetest/scope
/dependency
dependencygroupIdorg.junit.platform/groupIdartifactIdjunit-platform-suite/artifactIdversion1.8.2/versionscopetest/scope
/dependency
dependencygroupIdorg.seleniumhq.selenium/groupIdartifactIdselenium-java/artifactIdversion4.0.0/version
/dependency
!-- 文件保存相关 --
dependencygroupIdcommons-io/groupIdartifactIdcommons-io/artifactIdversion2.6/version
/dependency为了方便自动化测试这里关闭了项目的验证码功能。
1. 创建公共类
为了避免在使用时频繁创建Chrome驱动类我们可以定义一个功能类使用单例创建驱动对象。公共类里包含了保存截图的方法方便测试截图观察。
public class AutoTestUtil {private static volatile ChromeDriver driver;private static final String IMG_SAVE_DIR ./src/img/;private AutoTestUtil(){}public static ChromeDriver getDriver() {if (driver null) {synchronized (AutoTestUtil.class) {if (driver null) {ChromeOptions options new ChromeOptions();options.addArguments(--remote-allow-origins*);driver new ChromeDriver(options);// 设置隐式等待driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));}}}return driver;}/*** 获取格式化时间* return*/private static ListString getTime() {// 图片文件按照 包名.类名.方法名_时间搓区分SimpleDateFormat fileFormat new SimpleDateFormat(yyyyMMdd-HHmmssSS);// 图片目录按照天区分格式20230812SimpleDateFormat dirFormat new SimpleDateFormat(yyyyMMdd);String fileName fileFormat.format(System.currentTimeMillis());String dirName dirFormat.format(System.currentTimeMillis());ListString result new ArrayList();result.add(dirName);result.add(fileName);return result;}/*** 截图* param testFuncName 对应函数名* throws IOException*/public static void saveFileImg(String testFuncName) throws IOException {ListString times getTime();String fileName IMG_SAVE_DIRtimes.get(0)/ testFuncName_times.get(1).png;File file driver.getScreenshotAs(OutputType.FILE);FileUtils.copyFile(file,new File(fileName));}
}
2.注册页面UI自动化测试用例编写 在该测试中发现问题找不到警告弹窗。异常信息
因为我这里是采用的隐式等待隐式等待是对弹窗不起作用的代码执行过快就会出现代码执行到点击弹窗确定按钮而弹窗还没有出现。所以在点击之前将一个1秒的强制等待即可解决问题。 编写测试代码
通过TestMethodOrder(MethodOrderer.OrderAnnotation.class)保证测试用例的执行顺序对应的多个异常注册测试用例一个成功注册测试用例通过检测是否跳转登录页面来判断是否注册成功
// 使用方法排序
TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class RegAutoTest {private static ChromeDriver driver;BeforeAllstatic void init() {driver AutoTestUtil.getDriver();driver.get(http://120.25.124.200:7070/register.html);driver.manage().window().maximize();}/*** 检查注册页面是否正确打开* 检测点注册账号按钮是否显示*/TestOrder(1)void regCheckLoad() {driver.findElement(By.xpath(//*[id\reg_submit\]));}/*** 异常注册* param username* param password* param confirmPass*/ParameterizedTestOrder(2)CsvSource({null,admin,admin,admin,null,admin,admin,admin,null,admin,admin,add,hhy,hhy,hhy})void regFail(String username,String password,String confirmPass) throws InterruptedException {WebElement usernameElement driver.findElement(By.cssSelector(#reg_username));WebElement passwordElement driver.findElement(By.xpath(//*[id\reg_password\]));WebElement confirmPassElement driver.findElement(By.cssSelector(#confirm_pass));if (!username.equals(null)) {usernameElement.sendKeys(username);}if (!password.equals(null)) {passwordElement.sendKeys(password);}if (!confirmPass.equals(null)) {confirmPassElement.sendKeys(confirmPass);}driver.findElement(By.xpath(//*[id\reg_submit\])).click();Thread.sleep(2000);// 点击警告弹窗的确认按钮Alert alert driver.switchTo().alert();alert.accept();usernameElement.clear();passwordElement.clear();confirmPassElement.clear();}/*** 正常注册* param username* param password* param confirmPass*/Order(3)ParameterizedTestCsvSource({admin,admin,admin})void regSuccess(String username,String password,String confirmPass) throws InterruptedException {driver.findElement(By.cssSelector(#reg_username)).sendKeys(username);driver.findElement(By.cssSelector(#reg_password)).sendKeys(password);driver.findElement(By.xpath(//*[id\confirm_pass\])).sendKeys(confirmPass);driver.findElement(By.cssSelector(#reg_submit)).click();// 检测登录页面的元素来判断是否注册成功跳转// 检测登录按钮注册连接driver.findElement(By.xpath(//*[id\submit\]));driver.findElement(By.xpath(/html/body/div[2]/div[5]/a[1]));Thread.sleep(1500);}AfterAllstatic void quit() {driver.quit();}}
自动化测试演示
执行完毕后7个用列全部完成
3.登录页面UI自动化测试用例编写 根据测试用例编写对应代码
通过截图查看是否进入博客列表页面使用套件执行自动化测试代码
Suite
SelectClasses(LogInAutoTest.class)
public class RunSuite {
}TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class LogInAutoTest {private static ChromeDriver driver;BeforeAllstatic void init() {driver AutoTestUtil.getDriver();driver.get(http://120.25.124.200:7070/login.html);driver.manage().window().maximize();}/*** 检测登录页面是否正确打开* 检测点注册链接、登录按钮*/TestOrder(1)void loginCheckLoad() {driver.findElement(By.xpath(/html/body/div[2]/div[5]/a[1]));driver.findElement(By.xpath(//*[id\submit\]));}/*** 正常登录* param username* param password*/ParameterizedTestCsvSource({admin,admin,hhy,hhy})Order(3)void loginSuccess(String username,String password) throws IOException, InterruptedException {driver.findElement(By.xpath(//*[id\username\])).sendKeys(username);driver.findElement(By.cssSelector(#password)).sendKeys(password);driver.findElement(By.xpath(//*[id\submit\])).click();// 强制等待避免误截图Thread.sleep(1000);//将登录成功后的用户博客列表页面进行截图AutoTestUtil.saveFileImg(getClass().getName());driver.findElement(By.xpath(/html/body/div[1]/span[4]/a[3])).click();Thread.sleep(1000);Alert alert driver.switchTo().alert();alert.accept();Thread.sleep(1000);alert.accept();}/*** 异常登录* param username* param password*/ParameterizedTestCsvSource({null,null,null,admin,admin,null,admin,123,hello,000})Order(2)void loginFail(String username,String password) throws InterruptedException {WebElement usernameElement driver.findElement(By.xpath(//*[id\username\]));WebElement passwordElement driver.findElement(By.cssSelector(#password));if (!null.equals(username)) {usernameElement.sendKeys(username);}if (!null.equals(password)) {passwordElement.sendKeys(password);}driver.findElement(By.xpath(//*[id\submit\])).click();// 强制等待防止弹窗未出现Thread.sleep(1000);Alert alert driver.switchTo().alert();alert.accept();usernameElement.clear();passwordElement.clear();}AfterAllstatic void quit() {driver.quit();}
}自动化执行演示 登录自动化执行完毕后8个用例全部执行成功保存了用户博客列表页面的截图。
4.用户博客列表页面自动化测试 未登录的情况下通过检测url是否是登录页面来判断是否跳转正常登录场景下通过直接访问博客列表后判断是否存在写博客链接和文章标题判断是否正确打开
TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class UserBlogListAutoTest {private static ChromeDriver driver;BeforeAllstatic void init() {driver AutoTestUtil.getDriver();driver.manage().window().maximize();}/*** 未登录访问*/TestOrder(1)void userBlogListFail() {driver.get(http://120.25.124.200:7070/user_blog_list.html);// 获取当前页面url,判断未登录情况下是否跳转String url driver.getCurrentUrl();Assertions.assertEquals(http://120.25.124.200:7070/login.html,url);}/*** 进行正确登录* param username* param password*/ParameterizedTestCsvSource({admin,admin})Order(2)void loginSuccess(String username,String password) {driver.findElement(By.xpath(//*[id\username\])).sendKeys(username);driver.findElement(By.cssSelector(#password)).sendKeys(password);driver.findElement(By.xpath(//*[id\submit\])).click();}/*** 登录后访问* 检测点写博客链接,用户文章标题*/TestOrder(3)void userBlogListSuccess() {driver.get(http://120.25.124.200:7070/user_blog_list.html);driver.findElement(By.xpath(/html/body/div[1]/span[4]/a[2]));driver.findElement(By.cssSelector(body div.content div.mid div.show div h4));}AfterAllstatic void quit() throws InterruptedException {// 注销driver.findElement(By.xpath(/html/body/div[1]/span[4]/a[3])).click();Thread.sleep(1000);Alert alert driver.switchTo().alert();alert.accept();Thread.sleep(1000);alert.accept();driver.quit();}
}
自动化演示
5. 修改个信息页面 在进行修改信息页面测试时发现无法找到昵称输入框已经做了隐式等待。排查发现修改信息是在新窗口打开的所以要通过代码切换窗口来处理。 通过句柄跳转到用户个人信息页面
// 获取博客列表页面句柄String windows driver.getWindowHandle();// 点击修改资料链接driver.findElement(By.xpath(/html/body/div[2]/div[2]/div[1]/div[3]/a)).click();// 获取所有页面句柄SetString windowHandles driver.getWindowHandles();for (String s : windowHandles) {if (!s.equals(windows)) {// 切换到用户信息页面driver.switchTo().window(s);}}
自动化测试代码
TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class UpdateUserInfoAutoTest {private static ChromeDriver driver;BeforeAllstatic void init() {driver AutoTestUtil.getDriver();}/*** 未登录状态下访问用户信息修改页面*/TestOrder(1)void updateUserInfoFail() {driver.get(http://120.25.124.200:7070/updateInfo.html);driver.manage().window().maximize();}/*** 进行正确登录* param username* param password*/ParameterizedTestCsvSource({admin,admin})Order(2)void loginSuccess(String username,String password) {driver.findElement(By.xpath(//*[id\username\])).sendKeys(username);driver.findElement(By.cssSelector(#password)).sendKeys(password);driver.findElement(By.xpath(//*[id\submit\])).click();}/*** 登录成功场景修改个人昵称*/Order(3)Testvoid updateUserInfoSuccess() throws InterruptedException {// 获取博客列表页面句柄String windows driver.getWindowHandle();// 点击修改资料链接driver.findElement(By.xpath(/html/body/div[2]/div[2]/div[1]/div[3]/a)).click();// 获取所有页面句柄SetString windowHandles driver.getWindowHandles();for (String s : windowHandles) {if (!s.equals(windows)) {// 切换到用户信息页面driver.switchTo().window(s);}}Thread.sleep(1000);// 修改基本信息driver.findElement(By.cssSelector(#netName)).clear();driver.findElement(By.cssSelector(#netName)).sendKeys(网友);// 提交修改driver.findElement(By.xpath(//*[id\submitInfo\])).click();// 点击弹窗确认按钮Thread.sleep(1000);Alert alert driver.switchTo().alert();alert.accept();}/*** 登录状态上传头像错误格式,大小错误*/Order(4)ParameterizedTestCsvSource({C:\\Users\\HeHanYu\\Desktop\\code\\test.txt,C:\\Users\\HeHanYu\\Desktop\\壁纸\\wallhaven-d6eylg.jpg})void updateUserPhotoFail(String filePath) throws InterruptedException {// 获取文件上传按钮WebElement element driver.findElement(By.cssSelector(#uploadImg));// 指定路径选择文件element.sendKeys(filePath);// 点击上传头像driver.findElement(By.xpath(//*[id\submit\])).click();Thread.sleep(800);// 回退driver.navigate().back();}/*** 头像上传成功* throws InterruptedException*/Order(5)Testvoid updateUserPhotoSuccess() throws InterruptedException {// 获取文件上传按钮WebElement element driver.findElement(By.xpath(//*[id\uploadImg\]));// 指定路径选择文件element.sendKeys(C:\\Users\\HeHanYu\\Desktop\\code\\Python.jpg);Thread.sleep(1500);// 点击上传头像driver.findElement(By.xpath(//*[id\submit\])).click();// 回退driver.navigate().back();}AfterAllstatic void quit() throws InterruptedException {// 注销driver.findElement(By.xpath(/html/body/div[1]/span[4]/a[3])).click();Thread.sleep(1000);Alert alert driver.switchTo().alert();alert.accept();Thread.sleep(1000);alert.accept();driver.quit();}}
自动测试执行完成后测试用例全部通过 自动化测试演示
6. 文章编辑页面 根据用例编写代码
TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ArticleEditorAutoTest {private static ChromeDriver driver;BeforeAllstatic void init() {driver AutoTestUtil.getDriver();}/*** 未登录访问*/Order(1)Testvoid notLogin() {driver.get(http://120.25.124.200:7070/blog_editor.html);}/*** 进行正确登录* param username* param password*/ParameterizedTestCsvSource({admin,admin})Order(2)void loginSuccess(String username,String password) {driver.findElement(By.xpath(//*[id\username\])).sendKeys(username);driver.findElement(By.cssSelector(#password)).sendKeys(password);driver.findElement(By.xpath(//*[id\submit\])).click();}/*** 正确登录场景下打开* 检测点文章标题输入框是否存在*/Order(3)Testvoid openArticleEditor() {// 点击写博客链接driver.findElement(By.cssSelector(body div.nav span.links a:nth-child(2)));// 直接输入urldriver.get(http://120.25.124.200:7070/blog_editor.html);driver.manage().window().maximize();// 检测页面是否正确打开driver.findElement(By.cssSelector(#title));}/*** 错误发布示例* param title* throws InterruptedException*/ParameterizedTestCsvSource({null})Order(4)void postFail(String title) throws InterruptedException {if (!null.equals(title)) {driver.findElement(By.cssSelector(#title)).sendKeys(title);}driver.findElement(By.xpath(/html/body/div[2]/div[1]/button[1])).click();Thread.sleep(800);Alert alert driver.switchTo().alert();alert.accept();}ParameterizedTestCsvSource({博客标题})Order(5)void postSuccess(String title) throws InterruptedException {driver.findElement(By.cssSelector(#title)).sendKeys(title);driver.findElement(By.xpath(/html/body/div[2]/div[1]/button[1])).click();Thread.sleep(800);Alert alert driver.switchTo().alert();alert.accept();}AfterAllstatic void quit() {driver.quit();}}自动化演示
博客发布页面自动化测试用例全部通过
7. 设置密保问题 通过执行对应的错误测试用例执行正确的测试用例设置密保问题后去找回密码页面获取密保问题
代码编写
TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class SetQuestionPasswordAutoTest {private static ChromeDriver driver;BeforeAllstatic void init() {driver AutoTestUtil.getDriver();}/*** 未登录状态下访问*/Order(1)Testvoid notLogin() {driver.get(http://120.25.124.200:7070/set_questionPass.html);driver.manage().window().maximize();}/*** 进行正确登录进入到修改密码页面* param username* param password*/ParameterizedTestCsvSource({admin,admin})Order(2)void loginSuccess(String username,String password) throws InterruptedException {driver.findElement(By.xpath(//*[id\username\])).sendKeys(username);driver.findElement(By.cssSelector(#password)).sendKeys(password);driver.findElement(By.xpath(//*[id\submit\])).click();Thread.sleep(500);driver.get(http://120.25.124.200:7070/set_questionPass.html);}/**** 错误设置* param password* param answerOne* param answerTwo* param answerThree* throws InterruptedException*/ParameterizedTestCsvSource({null,one,two,three,test,one,two,null,test,one,null,three,test,null,two,three,test,one,two,three})Order(3)void setQuestionPassFail(String password,String answerOne,String answerTwo,String answerThree) throws InterruptedException {WebElement passElement driver.findElement(By.xpath(//*[id\password\]));WebElement oneElement driver.findElement(By.cssSelector(#oneValue));WebElement twoElement driver.findElement(By.xpath(//*[id\twoValue\]));WebElement threeElement driver.findElement(By.xpath(//*[id\threeValue\]));if (!null.equals(password)) {passElement.sendKeys(password);}if (!null.equals(answerOne)) {oneElement.sendKeys(answerOne);}if (!null.equals(answerTwo)) {twoElement.sendKeys(answerTwo);}if (!null.equals(answerThree)) {threeElement.sendKeys(answerThree);}// 获取Select问题标签Select selectOne new Select(driver.findElement(By.xpath(//*[id\one\])));Select selectTwo new Select(driver.findElement(By.xpath(//*[id\two\])));Select selectThree new Select(driver.findElement(By.xpath(//*[id\three\])));// 选取问题selectOne.selectByIndex(1);selectTwo.selectByIndex(1);selectThree.selectByIndex(1);//提交driver.findElement(By.xpath(//*[id\reg_submit\])).click();// 点击弹窗确认按钮Thread.sleep(500);driver.switchTo().alert().accept();// 清空输入框passElement.clear();oneElement.clear();twoElement.clear();threeElement.clear();}/**** 正确设置* param password* param answerOne* param answerTwo* param answerThree* throws InterruptedException*/ParameterizedTestCsvSource({admin,one,two,three})Order(3)void setQuestionPassSuccess(String password,String answerOne,String answerTwo,String answerThree) throws InterruptedException {WebElement passElement driver.findElement(By.xpath(//*[id\password\]));WebElement oneElement driver.findElement(By.cssSelector(#oneValue));WebElement twoElement driver.findElement(By.xpath(//*[id\twoValue\]));WebElement threeElement driver.findElement(By.xpath(//*[id\threeValue\]));// 填写密码和问题passElement.sendKeys(password);oneElement.sendKeys(answerOne);twoElement.sendKeys(answerTwo);threeElement.sendKeys(answerThree);// 获取Select问题标签Select selectOne new Select(driver.findElement(By.xpath(//*[id\one\])));Select selectTwo new Select(driver.findElement(By.xpath(//*[id\two\])));Select selectThree new Select(driver.findElement(By.xpath(//*[id\three\])));// 选取问题selectOne.selectByIndex(1);selectTwo.selectByIndex(1);selectThree.selectByIndex(1);//提交driver.findElement(By.xpath(//*[id\reg_submit\])).click();}/*** 检测问题是否设置成功*/TestOrder(4)void checkSetQuestion() throws InterruptedException {driver.get(http://120.25.124.200:7070/find_pass.html);Thread.sleep(1000);driver.switchTo().alert().accept();System.out.println(driver.getCurrentUrl());driver.findElement(By.xpath(//*[id\username\])).sendKeys(admin);driver.findElement(By.cssSelector(#reg div:nth-child(1) button)).click();String answer driver.findElement(By.xpath(//*[id\one\])).getText();System.out.println(answer);// 如果获取到了问题说明设置密保问题就成功了Assertions.assertNotEquals(问题1,answer);}AfterAllstatic void quit() {driver.quit();}
}
自动化演示
发现bug 设置获取的密保问题的断言执行了。 在执行多次设置密保问后都设置成功了但是在验证通过密保问题找回密码时发生了错误。 通过查看数据库的问题表发现了问题 同一个用户有多个问题存在数据表中原因是设置密保问题时没有对已经设置过密保的用户进行校验。导致多次插入数据引发查询到多条数据。
8. 所有用户文章列表页 在测试过程中发现为找到过期元素异常 发现是每次点击上一页或者下一页页面都会刷新所以导致元素失效原理的代码如下
Testvoid test() throws InterruptedException {WebElement first driver.findElement(By.cssSelector(body div:nth-child(3) div button.first));WebElement last driver.findElement(By.xpath(/html/body/div[3]/div/button[4]));WebElement front driver.findElement(By.xpath(/html/body/div[3]/div/button[2]));WebElement next driver.findElement(By.xpath(/html/body/div[3]/div/button[3]));first.click();Thread.sleep(1000);driver.switchTo().alert().accept();front.click();Thread.sleep(1000);driver.switchTo().alert().accept();next.click();Thread.sleep(1000);front.click();Thread.sleep(1000);last.click();Thread.sleep(1000);next.click();Thread.sleep(1000);driver.switchTo().alert().accept();last.click();Thread.sleep(1000);driver.switchTo().alert().accept();}改进代码每次切换页面后重新获取元素
public class BlogListAutoTest {private static ChromeDriver driver;static WebElement first;static WebElement last;static WebElement front;static WebElement next;BeforeAllstatic void init() {driver AutoTestUtil.getDriver();driver.get(http://120.25.124.200:7070/blog_list.html);driver.manage().window().maximize();}void get() {first driver.findElement(By.xpath(/html/body/div[3]/div/button[1]));last driver.findElement(By.xpath(/html/body/div[3]/div/button[4]));front driver.findElement(By.xpath(/html/body/div[3]/div/button[2]));next driver.findElement(By.xpath(/html/body/div[3]/div/button[3]));}Testvoid test() throws InterruptedException {get();first.click();Thread.sleep(1000);driver.switchTo().alert().accept();front.click();Thread.sleep(1000);driver.switchTo().alert().accept();next.click();get();Thread.sleep(1000);front.click();get();Thread.sleep(1000);last.click();get();Thread.sleep(1000);next.click();Thread.sleep(1000);driver.switchTo().alert().accept();get();last.click();Thread.sleep(1000);driver.switchTo().alert().accept();}AfterAllstatic void quit() {driver.quit();}
}自动化演示 9. 总结
通过Junit5单元测试工具配合selenium4自动化工具有如下亮点(好处)
使用注解避免生成过多对象造成资源和时间的浪费通过static修饰静态变量全局只创建一次驱动对象避免重复创建驱动对象造成时间的浪费使用参数化保持用例简洁提高了代码的可读性使用测试套件一次性执行所有我们想要运行的自动化用例使用等待隐式等待强制等待提高自动化指定的稳定性降低自动化出现误报的概率使用屏幕截图方便问题的追溯和问题的解决
三、性能测试
使用LoadRunner对项目做一个简单的性能测试性能测试在本机上进行测试测试云服务器太麻烦。
登录和所有文章列表页面是高频使用场景通过LoadRunner模拟多个用户进行并发进行登录后访问所有文章列表页面。
1.编写性能测试脚本
Action()
{//开启进入登录页事务lr_start_transaction(login_index);/* 注册获取返回参数该方法可以配合打印返回数据检测数据内容 */web_reg_save_param(ParaResult,LB,RB,LAST);// 定时检查点检测登录页面是否正确打开web_reg_find(Text登录,LAST);// 定义虚拟用户结合点lr_rendezvous(start);// 进入登录页面web_url(login_html,URLhttp://127.0.0.1:7070/login.html,TargetFrame,Resource0,Referer,LAST);// 结束进入登录页事务lr_end_transaction(login_index, LR_AUTO);//开启登录事务lr_start_transaction(login);// 进行登录web_submit_data(login,Actionhttp://127.0.0.1:7070/user/login,MethodPOST,EncTypeapplication/x-www-form-urlencoded; charsetUTF-8,TargetFrame,Referer,ModeHTTP,ITEMDATA,Nameusername, Valueusername, ENDITEM,Namepassword, Valuepassword, ENDITEM,LAST);//定时检测所有文章列表页检查点web_reg_find(Text查看全文,LAST);// 结束登录事务lr_end_transaction(login, LR_AUTO);//文章列表事务lr_start_transaction(blog_list);// 登录后访问所有文章列表页面web_url(blog_list,URLhttp://127.0.0.1:7070/blog_list.html,TargetFrame,Resource0,Referer,LAST);// 结束文章列表页事务lr_end_transaction(blog_list, LR_AUTO);return 0;
}点击测试
测试脚本没有问题后修改Action脚本的执行次数执行5次脚本
设置参数化
为了保证测试的合理性多个虚拟用户使用多个不同的账号进行登录使用LoadRunner的参数化即可实现。
2.创建测试场景
针对编写好的脚本通过Controller创建测试场景
1.设置15个虚拟用户
2.设置创建好测试场景后每5秒初始化3个虚拟用户
3.设置每5秒进入3个虚拟用户到测试场景 4.设置虚拟用户执行循环执行5分钟 5.设置虚拟用户执行完毕后每10秒退出5个虚拟用户 6.添加监视系统资源 CPU运行时间和剩余内存
3.开始执行 简单分析性能测试报告 在事务报告中一般只关注平均值和标准方差标准偏差值越大说明越不稳定。而且脚本里值是写3个事务而这里却有6个因为每个文件就是一个事务脚本文件中的init、action、end
运行的虚拟用户图表
通过虚拟用户运行图标发现在脚本运行40秒到5分30秒之间虚拟用户给了服务器负载 点击率表
通过点击率表可以看到和虚拟用户运行表运行对应起来虚拟用户的增多点击率也随之增多点击率越多说明和服务器的交互次数也越多。
吞吐量表
吞吐量图形和点击数图形有点相似但是吞吐量的曲线会稍后延后一点递增。因为吞吐量表示的是响应返回的资源数量所有是要先有请求才会有响应。 平均事务响应时间图
通过事务响应时间发现访问登录页面的时间比较长登录事务时间响应时间是比较短的深蓝是访问登录页面、黄色是登录事务、粉红色是进入文章列表页面在40秒的时候事务的响应时间达到最大那个时候正是15个虚拟用户生成完成进行访问服务导致一大波请求到达服务导致事务响应时间长。 虚拟用户在性能测试过程中每秒在服务器上命中的次数通过次图可以帮助根据命中次数评估虚拟用户生成的负载量
系统资源图表
precessorTimeCPU使用时间被消耗的处理器时间数量Available MBytes可用的物理内存一般根据这个指标推算消耗的物理内存有多大。已经消耗的物理内存实际内存 - 可用物理内存 CPU的占用时间从30多秒开始基本在长时间使用CPU对CPU的使用时间还是长的。因为本地使用的是自己的电脑而且并发设置了15对于电脑压力还是比较大的。 对应的这次测试对于内存的占用还不是特别高的。