Eclipse中 Junit 正常运行完了 可是方法覆盖率全红 解决办法 (附带②EclEmma插件安装方法④覆盖率抽出与合并)

58 篇文章 0 订阅
11 篇文章 0 订阅

■前言

今天修改完代码之后,修改对应的Junit。

对于目前这个工程,之前有一次案件对于,在整个工程中,使用Junit4 + JMockit方式,来实现Junit。

之前修改的测试类,都是通过以下方式实现的

XXXXXTest extends DJunitTestCase

而我修改的代码,之前的担当者,漏了修改了。

--------------------------

于是我修改代码如下 (粉色部分是我修改的)

@RunWith(JMockit.class)

XXXXXTest extends TestCase{

    @Test
     public void XXXTest() {。。。}

。。。。

}

修改之后,就出现了标题中描述的内容

Eclipse中 Junit 正常运行完了 可是方法覆盖率全红

--------------------------

■问题原因

Eclipse的EclEmma插件使用时,做了【除外:Excludes】的处理

比如,下面的位置,填写「com.sxz.demo.*」

那么,这个包下面所有的类,对应的Junit执行时,都不会统计覆盖率。

测试代码执行后,即使正常完了,每行代码都是红色,而不是期待的绿色。

(设置的目的:为了解决 类子的属性多出了一个 $jacocoData

      本文最下面,■相关知识2 中详细说明)

■问题原因推测(推测错误),但是内容是正确的

1.@Test注解与继承TestCase混用

---------------------------------
继承TestCase:Junit3的方式,方法名以test为前缀,  
方法名以test为前缀 , 方法名以test为前缀!!
@Test注解:Junit4的方式,方法上使用注解@Test
---------------------------------

2.继承 TestCase时,所有的标注(Annotation)失效

---------------------------------
所有方法,没有以test为前缀,@Test又失效了,

因此,该方法虽然正常执行了,但是么有被统计!!!

追记,今天看了代码,方法是以testXXX这种形式存在的。
---------------------------------

3.扩展

@BeforeClass和@AfterClass是JUnit4得新特性,
标记有@BeforeClass的方法会载所有的测试方法执行开始前运行,
标记有@AfterClass的方法会在所有的测试方法运行结束后执行。 

4.继承关系

TestCase继承了Assert

可以直接使用Assert中定义的镜头方法,简化代码

-----------------------------------

■相关知识1

1.Maven引用
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
</dependency>
<dependency>
  <groupId>org.jmockit</groupId> 
  <artifactId>jmockit</artifactId> 
  <version>1.21</version>
</dependency>

2.Eclipse中,Junit执行后,代码覆盖率相关的插件:EclEmma

3.代码相关

import mockit.Deencapsulation;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import mockit.Tested;
import mockit.Verifications;
import mockit.integration.junit4.JMockit;
 
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

 
@RunWith(JMockit.class)
public class HelloDemoTest {
 
    /**
     * mock公有方法
     */
    @Test
    public void testPublicMethod() {
        final HelloDemo hello= new HelloDemo ();
        // 设定期待值
        new Expectations(hello) {
            {
                hello.getAnything();
                result = 100;
                times = 1;
            }
        };

        // 断言
        Assert.assertEquals(100, hello.getAnything());
 
        // 方法执行次数
        new Verifications() {
            {
                hello.getAnything();
                times = 1;
            }
        };
    }
}

如果继承Assert,上面的断言就可以直接写了,不需要前面的类

4.关于反射

   问: 为什么我们会在Junit代码中,会经常看到反射的使用。

   回答:我们可以通过反射,调用类的私有方法

https://blog.csdn.net/fy_java1995/article/details/80088733

https://blog.csdn.net/yizhenn/article/details/52384582

5.DJunit 与  Eclipse  中的EclEmma 插件

    貌似使用这个插件,无法统计出来Djunit写的代码的覆盖率,

    所有,后来换成Junit4

6.Junit4 + JMockit

https://blog.csdn.net/yizhenn/article/details/52384582

===

Mockito和JMockit

JMockit、EasyMock、Mockito和PowerMock

https://www.jb51.cc/java/122225.html

===

7.反射相关的代码

    7.0 获取Class对象的三种方法

  1. Class.forName(“类的全限定名”)  // 下面我们将使用这一种
  2. 实例对象.getClass()
  3. 类名.class (类字面常量)

    7.1 调用构造函数创建类

// 反射的类,自定义了构造函数,构造函数中,只有一个String参数
// 每一个类都默认有一个无参的构造函数,但是但我们自己定义后,默认的无参的构造函数便消失了
// 如果父类是抽象类,继承父类,要实现父类的构造方法
// 也就是说,在自定义的构造方法的第一行,要写上supper();
Constructor<?> con = clazz.getDeclaredConstructor(String.class);
Object obj = con.newInstance("testName"); 

  7.2调用方法

Class clazz = Class.forName("Student");
Constructor<?> con = clazz.getConstructor(String.class, int.class);
Student student = (Student) con.newInstance("MyName", 18);
Method method=clazz.getMethod("myMethod", String.class);
method.invoke(student, "gogogo");

 上面的代码中,Student有一个两个参数的构造方法,和一个名字为「myMethod」的方法(此方法有一个String类型的参数)

https://blog.csdn.net/fy_java1995/article/details/80088733

 7.3 构造方法反射时的区别

・getDeclaredConstructor(Class<?>... parameterTypes) 
这个方法会返回制定参数类型的所有构造函数,包括public的和非public的,当然也包括private
・getDeclaredConstructors()
返回结果就没有参数类型的过滤,返回的是一个数组
・getConstructor(Class<?>... parameterTypes)
这个方法返回的是上面那个方法返回结果的子集,只返回制定参数类型访问权限是public的构造函数

----

■相关知识2 :EclEmma插件安装方法

8.Eclipse插件安装方法(非常简单)

8.1 Help -->Eclipse Marketplace

8.2 输入插件名字「EclEmma」然后回车,点击按照即可

■相关知识3(一般代码不会遇到这个坑)

使用覆盖率的方式执行测试代码时,类中会多出下面这个属性

$jacocoData(Java Code Coverage)

所有如果,使用反射取得类的属性(Fileds)时,会多取出来一个属性。

今天就遇到了这个问题,

正常执行Junit代码时,可以正常完了,

而是用覆盖率执行时,代码里面直接报错,说类的属性(Fields)的个数不正确。

因为,测试对象代码里面,取得了类的属性的个数进行判断,当不正确时,抛出异常

比如这个类里面有两个属性,正常执行时,取得的属性就是2个,所有没有问题;

而当使用覆盖率方式执行代码时,取得的属性个数是3个,不正确,抛出异常!

解决方法,把这个类,设置为覆盖率统计对象外,

这样,在Junit执行时,这个类便不会多出一个$jacocoData 属性来。

-----

■相关知识4 :覆盖率抽出与合并

■カバレッジ抽出(覆盖率抽出与合并)

https://www.cnblogs.com/Echo-41/p/6922993.html

(使用 Junit4 + JMockit ),按照下面步骤,可以到处覆盖率的文件

Java -> Coverage Report -> Next -> 选择导出格式(推荐HTML)-> 选择导出目录 -> Finished

(导出前,如果执行多次,可以合并多次执行后的覆盖率)

--------

step1

step2 (现在虽然安装了插件,但是没有使用Junit4,也许是因为这个原因,自己的电脑的Eclipse中看不到,

              但是,在单位的开发环境中是可以看到的。)

--

自己的电脑的效果如下(感觉和Junit4没有什么关系,应该是插件版本和Eclipse版本的问题)

-----

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值