目录
Junit是XUnit系列的一个单元测试框架,是用于Java下的,同理还有CppUnit,pyUnit。
这里使用的版本是JUnit4,与JUnit3相区分开来,简单来说。在Junit3中,如果某个类是测试类,必须将其继承类TestCase,如果某个方法是测试方法,必须让这个方法以test开头,如果希望指定某个测试方法运行之前运行某个初始化方法,这个方法的名称必须是setUp,如果希望在某个测试方法运行之后运行某个释放资源的方法,这个方法的名称必须是tearDown。
在junit4中,测试方法通过@Test来标识,初始化方法通过@Before来标识,释放资源的方法通过@After来标识,但是为了让junit4的测试类在junit3中也可以使用,习惯于把初始化方法命名为setUp,释放资源的方法命名为tearDown。Test中的测试方法一般以Test来开始。其中标识为Before注解的方法,每次运行测试类,都会执行标识为@After与@Before的方法。
注解就好像你可以在你的代码中添加并且在方法或者类中应用的元标签。
JUnit 中的这些注解为我们提供了测试方法的相关信息,哪些方法将会在测试方法前后应用,哪些方法将会在所有方法前后应用,哪些方法将会在执行中被忽略。
JUnit 中的注解的列表以及他们的含义:
| 序号 | 注解 | 描述 |
|---|---|---|
| 1 | @Test | 这个注解说明依附在 JUnit 的 public void 方法可以作为一个测试案例。 |
| 2 | @Before | 有些测试在运行前需要创造几个相似的对象。在 public void 方法加该注解是因为该方法需要在 test 方法前运行。 |
| 3 | @After | 如果你将外部资源在 Before 方法中分配,那么你需要在测试运行后释放他们。在 public void 方法加该注解是因为该方法需要在 test 方法后运行。 |
| 4 | @BeforeClass | 在 public void 方法加该注解是因为该方法需要在类中所有方法前运行。 |
| 5 | @AfterClass | 它将会使方法在所有测试结束后执行。这个可以用来进行清理活动。 |
| 6 | @Ignore | 这个注解是用来忽略有关不需要执行的测试的。 |
逻辑覆盖是白盒测试中动态测试中的一种典型方法,常用于单元测试。软件测试的方法根据是否透明分为黑盒测试和白盒测试两大类(灰盒测试这里不做讨论),也就是白盒测试专注于过程性的测试,黑盒测试专注于结果功能的是否实现。其中白盒测试根据是否执行代码可分为静态测试和动态测试,这里的逻辑覆盖就是一种典型的动态测试方法。那么白盒测试中的静态测试大家可想而知其实就是不运行代码去检查代码中的bug了。
逻辑覆盖可分为六种覆盖标准:其中为语句覆盖、判定覆盖、条件覆盖、条件判定覆盖、条件组合覆盖、路径覆盖。其中覆盖的强度依据上面的顺序依次增强。
判定覆盖:设计若干测试用例,运行被测试程序,使得每一条可执行程序至少执行一次。
判定覆盖:设计若干测试用例,运行被测程序,使程序中的每个判断的每个条件的每个可能取值至少执行一次。
条件覆盖:设计足够多的测试用例,运行被测程序,使程序中每个判断的每个条件的每个可能取值至少执行一次。
判定条件覆盖:设计足够多的测试用例,运行被测程序,使程序中每个判断的每个条件的可能取值至少执行一次,并且每个可能得判断结果也至少执行一次,即要求各个判断的所有可能的取值组合至少执行一次。
条件组合覆盖:设计足够多的测试用例,运行被测程序,使程序中每个判断的所有可能的条件取值组合至少执行一次。
路径覆盖:选取足够多的测试数据,使程序的每条可能路径都至少执行一次(如果程序图中有环,则要求每个环至少经过一次)。
//Example.java
public class Example {
public int logicTest(int x, int y) {
int magic = 0;
if( x > 0 && y > 0) {
magic = x + y + 10;
}else {
magic = x + y - 10;
}
if( magic < 0 ) {
magic = 0;
}
return magic;
}
}
//原创于CSDN博客Credic1017用户
1.对于语句覆盖,我们只需要一个测试用例就可满足标准:
测试用例1:预期输入x=1,y=1,预期输出magic=12.
2.对于判定覆盖,我们需要第一个判断和第二个判断都分别取一次True和False。故这里至少需要两个测试用例来满足判定覆盖:
测试用例2:预期输入x=2,y=2,预期输出magic=14(满足第一个判断为True,第二个判断为False)
测试用例3:预期输入x=3,y=-1,预期输出magic=0(满足第一个判断为False,第二个判断为True)
3.条件覆盖,我们这里需要满足6个条件,分别为:x>0,x≤0,y>0,y≤0,magic<0,magic≥0。易发现这里至少两个测试用例也可满足条件覆盖标准。
测试用例4:预期输入x=3,y=3,预期输出magic=16(满足条件x>0,y>0,magic≥0)
测试用例5:预期输入x=0,y=0,预期输出magic=0(满足条件x≤0,y≤0,magic<0)
4.条件判定覆盖,这里的话其实就是同时满足判定覆盖和条件覆盖,具体可见上面关于条件判定覆盖的理论。这里也只需要两个测试用例便可完成。
测试用例6:预期输入x=4,y=4,预期输出magic=18(满足条件x>0,y>0,magic≥0,第一个判断里面为True,第二个判断里面为False)
测试用例7:预期输入x=-1,y=0,预期输出magic=-1(满足条件x≤0,y≤0,magic<0,第一个判断里面为False,第二个判断里面为True)
5.条件组合覆盖,第一个判断里面可取TT、TF、FT、FF的一个组合情况,第二个判断里面可取T、F的一个情况,故这里至少需要四个测试用例才能满足。
测试用例8:预期输入x=2,y=3,预期输出magic=15
测试用例9:预期输入x=2,y=-1,预期输出magic=0
测试用例10:预期输入x=-1,y=20,预期输出magic=9
测试用例11:预期输入x=-2,y=-3,预期输出magic=0
6.路径覆盖:这里是对他的一个路径进行一个覆盖,需要先画出程序的控制流程图,然后通过公式计算出路径的条数。理论上的路径条数有四条,但是有一条走不通,故这里只有三条路径。
测试用例12:预期输入x=2,y=4,预期输出magic=16
测试用例13:预期输入x=-30,y=10,预期输出magic=0
测试用例14:预期输入x=-10,y=30,预期输出magic=10
package logicTest;
import org.junit.Before;
import org.junit.Test;
import junit.framework.TestCase;
public class ExampleTest {
Example c = null;
@Before
public void beforeClass() {
c = new Example();
}
@Test
//语句覆盖
public void testStatementCoverage(){
int result = c.logicTest(1, 1);
TestCase.assertEquals(result, 12);
}
@Test
//判定覆盖
public void testDecisionCoverage(){
int result = c.logicTest(2, 2);
TestCase.assertEquals(result, 14);
result = c.logicTest(3, -1);
TestCase.assertEquals(result, 0);
}
@Test
//条件覆盖
public void testConditionCoverage() {
int result = c.logicTest(3, 3);
TestCase.assertEquals(result, 16);
result = c.logicTest(0, 0);
TestCase.assertEquals(result, 0);
}
@Test
//条件判定覆盖
public void testConditionalDecisionCoverage() {
int result = c.logicTest(4, 4);
TestCase.assertEquals(result, 18);
result = c.logicTest(-1, -1);
TestCase.assertEquals(result, 0);
}
@Test
//条件组合覆盖
public void testConditionCombinationCoverage() {
int result = c.logicTest(2, 3);
TestCase.assertEquals(result, 15);
result = c.logicTest(2, -1);
TestCase.assertEquals(result, 0);
result = c.logicTest(-1, 20);
TestCase.assertEquals(result, 9);
result = c.logicTest(-2, -3);
TestCase.assertEquals(result, 0);
}
@Test
//路径覆盖
public void testPathCoverage() {
int result = c.logicTest(2, 4);
TestCase.assertEquals(result, 16);
result = c.logicTest(-30, 10);
TestCase.assertEquals(result, 0);
result = c.logicTest(-10, 30);
TestCase.assertEquals(result, 10);
}
}
//原创于CSDN博客Credic1017用户
下面是使用eclipse右键选择运行方式选择JUnit测试,得到的运行结果如下:(绿色代表运行通过,红色代表运行未通过,故障次数代表测试用例出错的次数,错误代表程序本身的错误个数,如果有故障存在可通过故障跟踪来定位故障。)

以上就是关于逻辑覆盖在eclipse中应用JUnit框架进行单元测试的一个总的流程,谨以此文记录学习软件测试逻辑覆盖测试过程中的一个心路历程,如有错误欢迎指正!
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h