• 2
  • 1
分享
  • 如何检验自身的技术水平?参加一场比赛就知道了
  • 恬恬圈 2019-12-10 13:33:50 字数 12456 阅读 2281 收藏 1

前言

我在CSDN上看到一篇名为《程序员为什么非要参加一场编程竞赛》的文章,这是一篇译文,原著是国外的作者。这让我想起前段时间我参加的一场软件测试比赛,最终的感想可以用8个字概括,人无远虑必有近忧。在这里我想和大家分享我的参赛过程和赛后总结。

一、赛事简介

比赛给人的第一印象就是激情,热血,因为比赛一定能分出高低。编程竞赛在国内出现的时间比较早,现在已经上规模,成体系了,加之媒体的报道,大家也比较熟悉。但是软件测试比赛或许大家还没听说过。实际上成体系的软件测试比赛,例如CST全国大学生软件测试大赛,在2016年就已经首次举办,今年已经是第四届了。赛事项目分有:单元测试、性能测试、安全测试、web自动化测试、APP自动化测试,嵌入式测试等,可谓是相当全面。赛程从初赛、省赛、决赛到国际赛,中间也会穿插一些其他比赛,例如欧洲邀请赛,以及一些工业性质的比赛。

我所参加是南京7月份软博会期间,举办的一场工业APP软件测试比赛。

二、赛程赛制

比赛分为个人赛和团队赛,团队赛每队3人。由于个人赛和团队赛是同时进行的,所以无法同时参加2个项目。比赛分为3个阶段,第一阶段是报名和练习,选手报名后,可以在官方网站阅读比赛规则和注意事项,还会开放一些练习题,帮助赛前热身;第二阶段是网络预选赛,比赛时间3小时。个人赛前60名,团队赛前20名,可以进入决赛;第三阶段是决赛,比赛时间3小时,在南京国际博览中心进行线下比赛。总奖金12万RMB。

三、评分标准

预选赛评分标准:

1. (60%)Selenium脚本的测试需求覆盖率以及成功回放率;

2. (40%)Jmeter性能测试脚本的场景设置和参数设定准确性以及成功回放率;

3. 总分=评分1+评分2,比赛有多道题则累加计算;

4. 总分相同的选手按测试用例集运行时间二次排名,运行时间短优先。

总决赛评分标准:

1. (40%)Selenium脚本的测试需求覆盖率以及成功回放率;

2. (20%)Jmeter性能测试脚本的场景设置和参数设定准确性以及成功回放率;

3. (30%)协作式众包测试,Bug报告编写(0.6)+Bug报告审核(0.4);

4. (10%)工业APP标准符合性评价

5. 总分=评分1+评分2+评分3+评分4,比赛有多道题则累加计算;、

6. 总分相同的选手按测试用例集运行时间二次排名,运行时间短优先。

Selenium脚本和jmeter脚本为自动化评分;其余由专家人工评分。

四、赛前准备和初赛

报名后,我在阅读注意事项时,看到其中一条“所有的IDE都需要从官网下载,并按照官方要求进行配置,否则无法得分”。于是我在赛事官网上下载Eclipse,Jmeter,jdk等。浏览器、第三方jar包、驱动器、笔记本电脑需要选手自备。由于平时工作较忙,练习基本没做过,只是体验了一下比赛流程。初赛时间是下午2点到5点,持续3个小时时间,看似很长,但是分析完需求文档后,我觉得时间还是挺赶的。比赛过程中,是允许多次提交代码的。每次提交完都会立刻显示当前提交代码所获得的评分。最终的得分并不是以多次提交中的最高分为准,而是以最后一次提交代码所获得的分数为准。这就需要我们自己做好版本控制,若后期提交的代码分数不高,可以在比赛结束前进行回滚,以获取最高分。由于参赛人数较多,所以jmeter在调试脚本时,不允许使用大并发数,否则IP会被服务器的安全协议禁用,导致调试失败且无法提交代码。可以用1个线程进行调试,然后提交的时候改成多线程。

五、决赛

决赛是线下比赛,比赛地点在南京国际博览中心。比赛时间早上9点到12点,可以在8点后进入场地,调试比赛机器。

当天处于软博会展会期间,参展人员很多,7月份天气又很热。到达现场已经是汗流浃背,心情比较浮躁。我是个喜欢比赛的人,中学参加过数学竞赛,大学参加过电子竞技,比赛经验也算比较丰富了。所以看到现场这么多人,我并没有紧张,但却也不平静。而是兴奋,因为这是我第一次参加和工作有关的比赛。找到我的位子后,我调整了一下心态,便开始调试机器。

9点准时开始比赛,发放需求文档。selenium自动化测试需要完成13个页面的操作和校验;jmeter需要完成3个接口的性能测试;手工测试则针对整个被测软件,大小页面加起来约上百个;最后还要对被测软件进行工业标准符合性评价。

看完文档我的第一感觉就是时间不够。于是我快速开始编写selenium脚本,大约2分钟时间,登录脚本写完,调试通过,但是代码提交后,显示运行得分为0,我认为是系统显示的问题,可能要等比赛结束才会显示分数。于是我继续编写脚本,我发现页面的iframe太多,来回切换比较费时,且被测系统也是一个陌生的环境,我便想着先进行手工测试,顺便熟悉下操作,然后再进行脚本编写。有了这个念头以后,我又重新看了一遍功能测试的需求文档,再次阅读后,我发现了一条重要的线索“当某位选手发布bug后,其余选手提交bug与该选手类似,则由专家判定,若确实相同,优先发布bug的选手得分,其余选手不得分”,需求中的原文我不记得了,但是理解后就是这个意思。我的天哪,这意味着手工测试的30分是抢分赛,如果我拿了10分,其余59人加起来只能拿到20分。此时已经9点50,我觉得这30分可能已经所剩无几了,我立刻提交当前selenium代码,开始转战手工测试,让我意外的是,仅10分钟的时候,我发布了15个bug,竟然没有一个是重复的,说明大部分选手并没有注意到这条规则的真正含义。我继续进行手工测试,渐渐的,开始出现重复bug,直到11点,几乎提交的bug都是重复bug。我知道大部分的人都在进行手工测试,且未被发现的bug也越来越少,也就是说手工测试这30分中,剩余的分数越来越少,相对于时间的紧迫性,我觉得剩余的bug性价比已经不高了。我便开始了jmeter脚本的编写,大约20分钟,没有任何阻碍,完成了性能脚本编写,提交后,虽然得分不高,但我不打算优化,毕竟jmeter的占比只有20%。

1.png

我将剩余的时间放在了selenium脚本的编写。提交后,得分依然是0,此时引起了我的注意,一开始我认为可能比赛后才会显示分数,但jmeter是立刻就给出了分数,我断定是selenium的评分机制出了bug。我开始检查脚本,我发现在设置启动主站点时,裁判给我们的是url中有一个单词是大写。

2.png

而在浏览器中,输入url,会被重定向成小写,

1.png

然后我修改了selenium脚本中的url,提交后,得分出来了。最后简单的写了一下工业符合性评价。手工测试我抢到了不少分,其他选手如果没有发现url这个问题,可能selenium这一项就是0分了,而我是有得分的。我觉得占据着两大优势,可以拿到一个不错的名次。距离结束还有20分钟的时候,有一位选手提出了疑问,为什么selenium提交是0分。裁判询问后,发现现场很多选手都是0分,于是组委会专家开始寻找问题,在距离比赛结束还有10分钟的时候,问题找到了。大家修改url后开始疯狂的提交代码,以至于服务器承受不住压力,出现了断开连接、长时间未响应等异常情况,裁判最后也是允许未提交成功的选手,可以由组委会使用U盘将代码从选手的机器拷贝出来,复制到服务器上。最终我获得的是二等奖。

六、赛后总结

这次比赛自动化编码和手工测试占据了大部分分值。关于比赛中selenium的编码,我从3个地方做一个总结。(以下是我比赛中编写的一部分代码)

public static void test(WebDriver driver) {
try {
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    driver.get("http://app.eedi.org.cn/SEEMMS.Server/public/index.php/index/login/login.html");
    driver.manage().window().maximize();
    driver.findElement(By.name("ACCOUNT")).sendKeys("test32");
    driver.findElement(By.name("PASSWORD")).sendKeys("752167");
    driver.findElement(By.name("ylogin")).click();
    Thread.sleep(1500);
    driver.findElement(By.id("a-Conditionmonitor")).click();
    driver.findElement(By.xpath("//*[@name='Conditionmonitor']/li[2]/a")).click();
    driver.findElement(By.xpath("//*[@id='add-panel']/div/a")).click();
    driver.findElement(By.name("SHAFT_SPEED")).sendKeys("10");
    driver.findElement(By.name("SHAFT_TQRQUE")).sendKeys("20");
    driver.findElement(By.name("SHAFT_POWER")).sendKeys("30");
    driver.findElement(By.name("THRUST_TQRQUE")).sendKeys("40");
    driver.findElement(By.name("THRUST_SPEED")).sendKeys("50");
    driver.findElement(By.name("THRUST_POWER")).sendKeys("60");
    driver.findElement(By.name("THRUST_THRUST")).sendKeys("70");
    Thread.sleep(1000);
    driver.findElement(By.xpath("//input[@value='确定']")).click();
    driver.findElement(By.id("alert")).click();
    Thread.sleep(1000);
    driver.findElement(By.xpath("/html/body/div[2]/div/div[2]/ul/li[2]/a")).click();

(1)定位问题。

传统的定位方式都是选择id和name,在没有id和name属性时,选择使用其他属性,例如link,css等,最后选用xpath。但随着技术发展,这些传统的规则也有些不适用了。因为id,name可能会重名,link可能被封装等等元素。

这段代码中有一部分我使用了xpath的方式去定位,但实际上这个元素是有id属性的。为什么我不用id去定位?因为现在很多前端页面,都是通过模板生成的或是程序员只写一种通用方法,每次重复生成页面元素。这就会产生下面这个现象:①id前缀相同,后缀是每次点击展开按钮时动态生成。这样的id每次都不一样。

1.png

②多个元素使用相同id

2.png

此时使用id就无法就精准定位,所以传统的定位规则已经不适合现在的前端了。不论什么规则,我们只要理解其思想就行了。我认为满足3个条件就是好的定位方法。一是当前环境可以精准定位,运行成功率100%;二是具有健壮性,未来前端发生改变,可能会增加页面元素等,原方法依然可以定位到;三是易阅读,方便其他人员维护代码。

例如上面的2个例子中,对于第一个树形结构,根据边界值测试的设计思想,我们需要定位首个或最后一个树节点,不能使用id去定位,那么可以写成这样:

List<WebElement> tree = driver.findElement(
                   By.xpath("//a[@title='安徽省']/following-sibling::ul"))
                    .findElements(By.tagName("li"));

先通过title找到安徽省,然后通过轴关键字找到其后的兄弟节点ul,最后将这个节点下所有的li元素全部加入到list中,那么以后不同权限的账号登录系统,无论其管理城市数量的多少,我们都可以通过

tree.size();  //获取当前账户权限管理的城市数量
tree.get(0);  //定位首个城市
tree.get(tree.size()-1); //定位最后一个城市

这2条语句定位到树结构的边界,对边界节点进行其他操作,完成边界测试。当然除了这3点,还有其他衡量的方法,例如增加冗余代码

3.png

这是百度首页,点击“百度一下”按钮的操作代码,可以看到selenium IDE提供了5种定位方式,日后若这个按钮发生了属性变化,则运行代码时,他会先从第一种定位方式进行页面元素寻找,若5种方式都找不到,才会报NoSuchElementException

(2)等待时间。

比赛中有提到程序运行同分的,以运行时间二次排名。那么我的代码中加入了以下语句

 Thread.sleep(1500);

这对于比赛显然是不利的,因为增加了运行时间。那为什么还要加等待时间呢?因为java执行速度过快,前端在执行页面跳转的过程中,java代码并不会停止,可能会产生页面还没有完全加载,java代码就已经执行下一句的,会导致无法找到页面元素报错。有时候我们看到NoSuchElementException报错时,并不是定位方法出了问题,而是页面加载速度跟不上java执行的速度。例如:

driver.findElement(By.name("ylogin")).click();    //点击登录按钮
Thread.sleep(1500);
driver.findElement(By.id("a-Conditionmonitor")).click();   //点击监视器按钮

系统登录后,会跳转到首页,首页右上角有一个监视器按钮。如果不加入第二行代码,就会报错。因为点击登录,页面跳转大约需要0.3秒的时间,但是此时java已经开始执行“点击监视器按钮”这个操作了,此时页面是空白的,所以无法找到元素,报错。加入等待1.5秒,页面完全加载成功,此时在执行“点击监视器按钮”操作,就可以正常运行了。有人会问既然要加等待时间,为什么选择这种固定的方式?动态等待,可以提高程序的执行速度呀?其实我是出于2点原因这么写的。第一是因为动态等待需要设置参照物,对于第一次测试这么庞大的系统,比赛时间又这么短,我不想把比赛时间浪费在脚本的性能调优上,能跑起来就行。第二是因为平时我做自动化测试时,都是以场景为设计对象,真实用户在操作时,每一步之间都会有停顿,我是尽可能的让机器去模仿用户的操作习惯,才这么写。用过LoadRunner的人都明白什么是“思考时间”,其实我这样写,就相当于是“思考时间”。当然,如果是追求全功能的回归测试,那么提高效率,还是应该使用动态等待。

(3)测试类,功能类,配置类应该分开去写。

而比赛中,官方提供的模板是

4.png

Example.java内容如下:

import java.util.concurrent.TimeUnit;
public class Example {
   // Mooctest Selenium Example
 // <!> Check if selenium-standalone.jar is added to build path.
   public static void test() {   }
    public static void main(String[] args) {
       // Run main function to test your script.   }
}

主类用于运行,测试类用于功能编写。也许是方便比赛评分吧。但实际中我认为测试类,功能类,配置类需要分开。这样易读且方便维护。

①这是配置类。定义了打开和关闭浏览器。打开浏览器需要的驱动、url、超时时间等。因为每次测试,都需要这些固定的步骤,所以单独写成一个配置类,如果测试地址改了,只需要在这里修改一次url就行了。如果功能、配置、运行写在一个文件中,那么一旦发生修改,你就要去所有的文件中修改。

public class OpenAndCloseBrowse {
String baseUrl = "http://app.eedi.org.cn/SEEMMS.Server/public/index.php/index/login/login.html";
    public WebDriver openMethod(WebDriver driver) {
       System.setProperty("webdriver.chrome.driver",
                "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chromedriver.exe");
       driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        driver.get(baseUrl);
        driver.manage().window().maximize();
        return driver;
    }
   public void closeMethod(WebDriver driver) {
        driver.quit();
    }
}

②这是运行类(测试类)。定义了要进行哪些测试,与测试用例对接。第11行代码中的username和password,可以写成从测试用例中动态获取。

public class Login_TestCase {
    public WebDriver driver;
    @Test(description = "正常登录")
    public void normalLogin() {
       OpenAndCloseBrowse b = new OpenAndCloseBrowse();
        driver = b.openMethod(driver);
        try {
            Login l = new Login();
           Thread.sleep(2000);
           l.login(driver, "username", "password");
      } catch (Exception e) {
           e.printStackTrace();
       } finally {
            b.closeMethod(driver);
        }
    }   @Test(description = "账号密码正确,无权限")
  @Test(description = "输入错误密码登录")
    @Test(description = "输入不存在的用户名登录")
   ......
}

③这是功能类。写了一个简短的登录功能。

public class Login {
public void login(WebDriver driver, String username, String password) {
    SQLMethod sql = new SQLMethod();
    String mobile = sql.getString("select mobile from user where mobile = '" + username + "'");
    int role = sql.getInt("select role from user where and mobile = '" + username + "'");
    String passwd = sql.getString("select password from user where mobile = '" + username + "'");
    String sign = "";
    // 没有输入约定好传no
    try {
        if (!username.equals("no")) {
           sign = "没有找到用户名输入框";
          driver.findElement(By.id("phone")).sendKeys(username);
       }
        if (!password.equals("no")) {
           sign = "没有找到密码输入框";
           driver.findElement(By.id("password")).sendKeys(password);
       }
       sign = "没有找到登录按钮";
   driver.findElement(By.xpath("//*[contains(text(),'登录')]/parent::button")).click();
        Thread.sleep(500);
       if (username.equals(mobile)) {
            if (password.equals(passwd)) {
                if (role == 1) {
                    // 正常登录
                   Thread.sleep(2000);
                   assertTrue(driver.getCurrentUrl().contains("HomePage"), "登录成功,
                      跳转页面错误");
               } else {
                    // 帐号密码正确,权限不足
                    sign = "用户无权限,没有给出提示";
                   assertEquals(driver.findElement(By.xpath("//*[@title='msg']")).getText()
                               .replaceAll(" ", ""), "用户无权限", "用户无权限,提示信息不正确");
                }
           } else if (password.equals("no")) {
               // 正确帐号,不输入密码
              sign = "不输入密码,没有给出提示";
                assertEquals(driver.findElement(By.xpath("//*[@title='msg']")).getText()
                  .replaceAll(" ", ""), "请输入正确的手机号/密码!", "不输入密码,提示信息不正确");
            } else {
               // 正确帐号,错误密码
                sign = "输入错误的密码,没有给出提示";
              assertEquals(driver.findElement(By.xpath("//*[@title='msg']")).getText()
                   .replaceAll(" ", ""), "密码错误", "输入错误的密码,提示信息不正确");
             }
        } else {
             if (username.equals("no")) {
               if (password.equals("no")) {
                   // 不输入帐号和密码
                 sign = "不输入帐号和密码,没有给出提示";
                  assertEquals(driver.findElement(By.xpath("//*[@title='msg']")).getText()
                      .replaceAll(" ", ""), "请输入正确的手机号/密码!");
                } else {
                   // 不输入帐号,正确密码
                    sign = "不输入帐号,没有给出提示";
                   assertEquals(driver.findElement(By.xpath("//*[@title='msg']")).getText()
                           .replaceAll(" ", ""), "请输入正确的手机号/密码!");
                }
            } else if (this.isInteger(username)) {
                // 不存在的帐号,正确密码
                sign = "输入不存在的帐号,没有给出提示";
                assertEquals(driver.findElement(By.xpath("//*[@title='msg']")).getText()
                        .replaceAll(" ", ""), "账户不存在", "输入不存在的帐号,提示信息不正确");
           } else {
                // 帐号格式错误
                sign = "输入错误格式的帐号,没有给出提示";
               assertEquals(driver.findElement(By.xpath("//*[@title='msg']")).getText()
                        .replaceAll(" ", ""), "请输入正确的手机号/密码!");
          }
        }
    } catch (NoSuchElementException e) {
       assertEquals(false, sign);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
   public boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+] [\\d]*$");
        return pattern.matcher(str).matches();
    }
}

对于设计的自动化测试用例,每一条用例的操作步骤,都可以写成功能类;每一个条用例所需要的测试数据,可以写入到运行类(测试类);每一条用例的前置条件,可以写入到配置类;每一条用例的预期结果,写入到功能类,用断言的方式实现,并将实际结果返回给运行类(测试类),可以拓展一下,将实际结果回填到测试用例中。再集成到jenkins,实现定时自动化测试。我们只要定期维护测试用例和脚本即可。

赛后我还在难过,如果没有选手质疑,可能大部分人第一项都是0分,或许我可以因此捡漏,拿到特等奖。但细想现实生活中,捡漏犹如彩票中奖,几率小且可遇不可求,想要拿到更高的奖项还是要提高自己。现阶段,软件测试比赛还是以大学生为主,纵观历届比赛,各分项赛对技能的标准和要求也是非常高的,能来参加比赛的学生都不是善茬,将来毕业后,就业,一定会对测试行业产生冲击。例如这次特等奖的选手,就是南京大学毕业的学生,已入职微软公司。若不想别淘汰,就要持续学习,努力奋进。

生活在和平年代的我们,衣食无忧,在欢声笑语中长大。但这样的环境来之不易。尤其是观看完国庆阅兵后,这种紧迫感更加强烈。当下“持续学习”,“努力奋进”是2个比较流行的词语,也完美的诠释了如何做,才能居安思危。作为一个IT人,持续学习和努力奋进,说的小一点,可以提升自己的竞争力,改善自己的生活;说的大一点是在为祖国的伟大复兴做贡献。举个例子,2001年中美黑客大战,大战结果也是众说纷纭,我不做过多评论。但从测试的角度去分析这件事情,当时我国IT从业人员少,且能力弱。各门户网站无论是性能、还是安全都相对较弱。而今天我国IT行业的发展,无论是AI、5G又或者是物联网,都是世界领先,且质量是非常有保障的,若IT人员可以持续学习和努力奋进,将学习所得运用到实际生产。再次爆发黑客大战时,无论是网站还是产品都可以保持高质量(包括功能,性能,安全等等),可能就像康辉说的那样“不愿打,但也不怕打,必要时不得不打”。无论是为了国家,还是为了自己,都要想的长远一些,正所谓人无远虑,必有近忧。“持续学习,努力奋进”不是一个口号,而是要付出实际行动的,或许这是我们这一代人最好的出路。


版权声明:本文出自51Testing会员投稿,51Testing软件测试网及相关内容提供者拥有内容的全部版权,未经明确的书面许可,任何人或单位不得对本网站内容复制、转载或进行镜像,否则将追究法律责任。

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 什么是大数据大数据是指无法在一定时间范围内用传统的计算机技术进行处理的海量数据集。对于大数据的测试则需要不同的工具、技术、框架来进行处理。大数据的体量大、多样化和高速处理所涉及的数据生成、存储、检索和分析使得大数据工程师需要掌握极其高的技术功底。需要你学习掌握更多的大数据技术、Hadoop、Mapreduce等等技术。大数据测试策略大数据应用程序的测试更多的是去验证其数据处理而不是验证其单一的功能特色。当然在大数据测试时,功能测试和性能测试是同样很关键的。对于大数据测试工程师而言,如何高效正确的验证经过大数据工具/框架成功处理过的至少百万兆字节的数据将会是一个巨大的挑战。因为大数据高效的处理测...
            14 14 907
            分享
          • 我从一个一窍不通的测试小白,摸爬滚打到今天,在公司担任测试组长,管理公司的测试组,总觉得软件测试人员不容易。但是,还是对软件测试这个行业满腔热血(至少目前是)。这几年来,跳的坑实在不少,有些也是自己挖。今天就来谈谈我的一些经验总结。从测试小白到测试组长,谈谈我的测试过程及管理经验总结一、测试过程的经验总结:1、测试过程中遇到严重的问题,除了登记在bug管理系统,也要反馈给领导。为什么要反馈给领导?因为很多事情就算是让你背锅,你也背不起的,反馈给领导,领导会帮忙监督开发并给出意见。特别是紧急项目,不要在测试完的时候才给领导反馈,在测试过程就可以反馈了。2、保管好自己的测试机子,不要轻易让软件开发...
            0 0 1145
            分享
          •   据报道,流行的流媒体服务Netflix正计划从2023年初开始打击密码共享。  Netflix早就知道密码共享是一个影响其利润的问题,但2020年订阅量的上升使该公司暂时没去解决这个问题。随着今年收入的下降和Netflix10年来首次出现用户流失,Netflix首席执行官里德-哈斯廷斯(ReedHastings)决定是时候对这个已经被搁置太久的问题采取行动了。  从2023年开始,Netflix计划要求向家庭以外的其它人共享账户的人进行付费。Netflix已经在一些拉美国家测试了密码共享的附加支付政策,会额外收取约3美元。在这些国家,主要账户所有者必须向家庭以外想要访问该账户的人提供一个验...
            0 0 1037
            分享
          • 1.什么是接口?接口测试主要用于外部系统与系统之间以及内部各个子系统之间的交互点,定义特定的交互点,然后通过这些交互点来,通过一些特殊的规则也就是协议,来进行数据之间的交互。2.接口都有哪些类型?接口一般分为两种:1.程序内部的接口 2.系统对外的接口系统对外的接口:比如你要从别的网站或服务器上获取资源或信息,别人肯定不会把数据库共享给你,他只能给你提供一个他们写好的方法来获取数据,你引用他提供的接口就能使用他写好的方法,从而达到数据共享的目的。程序内部的接口:方法与方法之间,模块与模块之间的交互,程序内部抛出的接口,比如bbs系统,有登录模块、发帖模块等等,那你要发帖就必须先登录,那么这两个...
            12 12 2596
            分享
          • 一、什么是HttpUnitHttpUnit是基于JUnit构建的一个开源的测试框架,专门针对Web应用的测试,用于解决使用JUnit框架无法对远程Web内容进行测试的问题。二、工作原理HttpUnit通过模拟浏览器的行为,包括提交表单(form)、处理页面框架(frames)、基本的http验证、cookies以及页面跳转(redirects)处理等,进行Web应用程序的测试。通过HttpUnit提供的功能,用户可以方便地与服务器端进行信息的交互,将返回的网页内容作为普通文本、XML Dom对象或者是作为链接、页面框架、图像、表单、表格等的集合进行处理,然后使用Junit框架进行测试,还可以导...
            0 0 2189
            分享
      • 51testing软件测试圈微信