Analyse complète de l'utilisation de JUnit

Introduction

JUnit est un framework de test unitaire et un framework de test de régression pour le langage de programmation Java .

Fonctionnalités de JUnit :

  • cadre open source
  • Fournir des annotations pour identifier les méthodes de test
  • Fournir des assertions pour tester les résultats attendus
  • TestRun est fourni pour exécuter des tests.
  • Courez vite, élégant et simple
  • Peut s'exécuter automatiquement, vérifier ses propres résultats et fournir un retour immédiat

utiliser

Affirmation

L'assertion est la fonction principale de JUnit, et toutes les assertions de JUnit sont contenues dans la classe Assert.

Les principales méthodes de la classe Assert sont les suivantes :

nom de la méthode description de la méthode
assertEquals Affirmer que la valeur attendue transmise est égale à la valeur réelle
assertNotEquals Affirmer que la valeur attendue transmise n'est pas égale à la valeur réelle
assertArrayEquals Affirmer que le tableau attendu transmis est égal au tableau réel
assertNull Affirmer que l'objet transmis est nul
assertNotNull Affirmer que l'objet transmis n'est pas nul
assertTrue affirmer que la condition est vraie
assertFalse Affirmer que la condition est fausse
assertSame Affirmer que deux objets font référence au même objet, équivalent à "=="
assertNotSame Affirmer que deux objets font référence à des objets différents, équivalent à "!="
affirmer que Confirme si une valeur réelle satisfait une condition spécifiée

Remarque : Les méthodes ci-dessus sont toutes des méthodes statiques de Assert, appelées par Assert.xxx, si vous devez appeler directement, vous devez ajouterimport static org.junit.Assert.*;

ordre d'exécution

Dans JUnit, l'ordre d' exécution est déterminé par les annotations @BeforeClass, @Before, et .@Test@After@AfterClass

annotation introduire
@beforeClass() Les méthodes annotées sont exécutées en premier, et une seule fois.
@afterClass() Les méthodes annotées sont exécutées en dernier et une seule fois.
@before() Les méthodes annotées sont exécutées pour chaque cas de test, mais avant que le cas de test ne soit exécuté.
@after() Les méthodes annotées sont exécutées pour chaque cas de test, mais après l'exécution du cas de test.
@Test Entre la méthode before() et la méthode after(), chaque cas de test est exécuté. L'ordre d'exécution est déterminé par l'emplacement du code

Les exemples sont les suivants :

   @BeforeClass
    public static void beforeClass() {
    
    
        System.out.println("in before class");
    }

    //execute only once, in the end
    @AfterClass
    public static void  afterClass() {
    
    
        System.out.println("in after class");
    }

    //execute for each test, before executing test
    @Before
    public void before() {
    
    
        System.out.println("in before");
    }

    //execute for each test, after executing test
    @After
    public void after() {
    
    
        System.out.println("in after");
    }

    //test case 1
    @Test
    public void testCase1() {
    
    
        System.out.println("in test case 1");
    }

    //test case 2
    @Test
    public void testCase2() {
    
    
        System.out.println("in test case 2");
    }

Le résultat est montré dans la figure:
insérez la description de l'image ici

écrire des tests

Voici le programme de chiffrement que nous allons tester

public class Encryption {
    
    
    /**
     * 加密程序,算法是将字符串反转,如 abc 会转为为 cba
     * @param content
     * @return
     */
    public static String encryption(String content){
    
    
       if (content == null)throw new NullPointerException();
       if (content.length() < 2)return content;
       char[] data = content.toCharArray();
       int size = data.length;
       for (int i = 0; i < size/2; i++) {
    
    
            char c = data[i];
            data[i] = data[size - i - 1];
            data[size - i - 1] = c;
       }
       return new String(data);
    }
}

Le code de test est le suivant

public class EncryptionTest {
    String content = "abc";
    @Test
    public void encryption() {
        assertEquals(Encryption.encryption(content),"cba");
    }
}    

essai paramétrique

Dans le code de test ci-dessus, il est très difficile de définir la valeur correspondante à chaque fois qu'une méthode est testée. Junit 4 introduit un nouveau test fonctionnel paramétré. Les tests paramétrés permettent aux développeurs d'exécuter le même test encore et encore avec des valeurs différentes. Vous suivrez 5 étapes pour créer des tests paramétrés.

  1. Utilisez @RunWith(Parameterized.class)pour annoter EncryptionTestla classe.
  2. Créez une @Parameterized.Parametersméthode statique publique annotée qui renvoie une collection (tableau) d'objets à utiliser comme collection de données de test.
  3. Créez un constructeur public pour EncryptionTest qui accepte l'équivalent d'une ligne de données de test.
  4. Créez une variable d'instance pour chaque colonne de données de test.
  5. Créez vos cas de test en utilisant des variables d'instance comme source de données de test.

code afficher comme ci-dessous:

@RunWith(Parameterized.class)
public class EncryptionTest {
    
    

    String result;

    String content;

    public EncryptionTest(String content, String result) {
    
    
        this.content = content;
        this.result = result;
    }

    @Parameterized.Parameters
    public static Collection primeNumbers(){
    
    
        return Arrays.asList(new Object[][]{
    
    
                {
    
    "abc","cba"},
                {
    
    "1234","4321"},
                {
    
    "",""}
        });
    }

    @Test
    public void encryption() {
    
    
        System.out.println("content = "+content+"  result = "+result);
        assertEquals(Encryption.encryption(content),result);
    }
}

Les résultats des tests sont présentés dans la figure :
insérez la description de l'image ici

test d'exception

Lorsque nous entrons dans content = null, une exception sera levée. Alors, comment testons-nous les conditions anormales, cela nécessite l'utilisation de paramètres @Testd'annotation expected, la valeur du paramètre est l'anomalie à détecter. Si l'exception correspondante est levée, le test réussit ; sinon, le test échoue.

code afficher comme ci-dessous:

    @Test(expected = NullPointerException.class)
    public void encryption() {
    
    
        System.out.println("content = "+content+"  result = "+result);
        assertEquals(Encryption.encryption(content),result);
    }

essai de temps

Parfois, nous devons tester l'efficacité d'un certain module, nous devons tester le temps d'exécution. Nous pouvons timeout déterminer le temps d'exécution maximal en millisecondes grâce aux paramètres de @Test.

code afficher comme ci-dessous:

    @Test(timeout = 1000)
    public void encryption() {
    
    
        System.out.println("content = "+content+"  result = "+result);
        assertEquals(Encryption.encryption(content),result);
    }

test asynchrone

Principe : le principe des tests asynchrones consiste à bloquer le thread de test, puis à exécuter le thread de test après l'exécution du thread asynchrone.

Ici utilisation waitet notiftyAllméthode à réaliser, le code est le suivant

/**
*要测试的类
*/
public class Simple {
    
    

    public interface Callback{
    
    
        void finish(String result);
    }

    private Callback callback;

    public void setCallback(Callback callback) {
    
    
        this.callback = callback;
    }

    public void deal(){
    
    
        new Thread(){
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    //模拟耗时操作
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                callback.finish("完成");
            }
        }.start();
    }
}


/**
*测试类
*/
public class SimpleTest {
    
    
    private Object lock = new Object();
    private int flag = 0;
    String res = null;
    @Test
    public void deal(){
    
    
         Simple simple = new Simple();
         simple.setCallback(result -> {
    
    
             synchronized (lock){
    
    
                 flag = 1;
                 lock.notifyAll();
             }
             res = result;
         });
         simple.deal();
             synchronized (lock){
    
    
                 while (flag == 0){
    
    
                     try {
    
    
                         lock.wait();
                     } catch (InterruptedException e) {
    
    
                         e.printStackTrace();
                     }
                 }
             }
        assertEquals(res,"完成");
    }
}

affirmer que

Transfert des tests unitaires Android (1) :assertThat l'utilisation du framework JUnit

Certaines des assertions de base que nous avons utilisées ci-dessus, si nous ne définissons pas les informations de sortie lorsque l'échec se produit, alors seule une AssertionError sera levée lorsque l'assertion échoue, et il est impossible de savoir quelle partie est erronée. Et assertThat nous aide à résoudre ce problème. C'est plus lisible.

assertThat(T actual, Matcher<? super T> matcher);

assertThat(String reason, T actual, Matcher<? super T> matcher); 

Parmi eux, raison est l'information de sortie lorsque l'assertion échoue, réel est la valeur de l'assertion et matcher est le matcher de l'assertion.

Classements de matcher couramment utilisés :

matcher illustrer exemple
est Affirme que l'argument est égal à l'expression de correspondance donnée plus tard assertThat(5, est (5));
pas Affirmer que l'argument n'est pas égal à l'expression correspondante donnée plus tard assertThat(5, not(6));
égal à Les arguments d'assertion sont égaux assertThat(30, equalTo(30));
equalToIgnoringCase Affirmer l'égalité des chaînes en ignorant la casse assertThat("Ab", equalToIgnoringCase("ab"));
contientString Affirmer qu'une chaîne contient une chaîne assertThat("abc", containsString("bc"));
commence avec Affirmer qu'une chaîne commence par une certaine chaîne assertThat("abc", commencePar("a"));
se termine par Affirmer qu'une chaîne se termine par une certaine chaîne assertThat("abc", se termine par("c"));
valeur null Affirmer que la valeur du paramètre est null assertThat(null, nullValue());
notNullValue Affirmer que la valeur du paramètre n'est pas nulle assertThat("abc", notNullValue());
plus grand que Affirmer que l'argument est supérieur à assertThat(4, supérieur(3));
moins que Affirmer que l'argument est inférieur à assertThat(4, moinsQue(6));
Plus grand ou égal à Affirmer que l'argument est supérieur ou égal à assertThat(4,supérieuràouégalà(3));
inférieur ou égal à Affirmer que l'argument est inférieur ou égal à assertThat(4, lessThanOrEqualTo(6));
proche de Affirmer qu'un nombre à virgule flottante se trouve dans une certaine plage assertThat(4.0, closeTo(2.6, 4.3));
tous Affirmer que toutes les conditions sont remplies, équivalent à && assertThat(4,allOf(greaterThan(3), lessThan(6)));
n'importe quel Affirmer qu'une condition est remplie, équivalente ou assertThat(4,anyOf(greaterThan(9), lessThan(6)));
hasKey 断言Map集合含有此键 assertThat(map, hasKey(“key”));
hasValue 断言Map集合含有此值 assertThat(map, hasValue(value));
hasItem 断言迭代对象含有此元素 assertThat(list, hasItem(element));

下图为使用assertThat测试失败时所显示的具体错误信息。可以看到错误信息很详细!
insérez la description de l'image ici

当然了匹配器也是可以自定义的。这里我自定义一个字符串是否是手机号码的匹配器来演示一下。

只需要继承BaseMatcher抽象类,实现matches与describeTo方法。代码如下:

public class IsMobilePhoneMatcher extends BaseMatcher<String> {
    /**
     * 进行断言判定,返回true则断言成功,否则断言失败
     */

    @Override
    public boolean matches(Object item) {
        if (item == null) {
            return false;
        }

        Pattern pattern = Pattern.compile("(1|861)(3|5|7|8)\\d{9}$*");
        Matcher matcher = pattern.matcher((String) item);

        return matcher.find();
    }

    /**
     * 给期待断言成功的对象增加描述
     */
    @Override
    public void describeTo(Description description) {
        description.appendText("预计此字符串是手机号码!");
    }

    /**
     * 给断言失败的对象增加描述
     */
    @Override
    public void describeMismatch(Object item, Description description) {
        description.appendText(item.toString() + "不是手机号码!");
    }
}

@Rule用法

转自Android单元测试(一):JUnit框架的使用的@Rule用法

还记得一开始我们在@Before与@After注解的方法中加入”测试开始”的提示信息吗?假如我们一直需要这样的提示,那是不是需要每次在测试类中去实现它。这样就会比较麻烦。这时你就可以使用@Rule来解决这个问题,它甚至比@Before与@After还要强大。

自定义@Rule很简单,就是实现TestRule 接口,实现apply方法。代码如下:

public class MyRule implements TestRule {
    
    

    @Override
    public Statement apply(final Statement base, final Description description) {
    
    

        return new Statement() {
    
    
            @Override
            public void evaluate() throws Throwable {
    
    
                // evaluate前执行方法相当于@Before
                String methodName = description.getMethodName(); // 获取测试方法的名字
                System.out.println(methodName + "测试开始!");

                base.evaluate();  // 运行的测试方法

                // evaluate后执行方法相当于@After
                System.out.println(methodName + "测试结束!");
            }
        };
    }

}

我们使用一下我们自定义的MyRule,效果如图:

insérez la description de l'image ici

JUnit - 框架扩展

Cactus

Cactus 是一个简单框架用来测试服务器端的 Java 代码(Servlets, EJBs, Tag Libs, Filters)。Cactus 的设计意图是用来减小为服务器端代码写测试样例的成本。它使用 JUnit 并且在此基础上进行扩展。Cactus 实现了 in-container 的策略,意味着可以在容器内部执行测试。

JWebUnit

JWebUnit est un framework de test basé sur Java pour les applications Web. Il intègre des frameworks existants tels que HtmlUnit et Selenium avec une interface de test unifiée et simple pour vous permettre de tester rapidement l'exactitude des applications Web.

JWebUnit fournit une API Java de haut niveau pour travailler avec des applications Web qui intègre une série d'assertions qui vérifient l'exactitude du programme. Cela inclut la transmission de liens, le remplissage et la soumission de formulaires, la validation du contenu du formulaire et d'autres fonctionnalités commerciales typiques des applications Web.

XMLUnit

XMLUnit fournit une seule classe d'extension JUnit, XMLTestCase, et quelques classes de support qui autorisent les assertions :

  • Comparez deux fichiers XML pour les différences (en utilisant les classes Diff et DetailsDiff)
  • Validation d'un fichier XML (en utilisant la classe Validator)
  • Le résultat de la transformation d'un fichier XML à l'aide de XSLT (en utilisant la classe Transform)
  • Évaluation des expressions XPath pour un document XML (en implémentant l'interface XPathEngine)
  • Un nœud autonome après la traversée DOM d'un fichier XML (en utilisant la classe NodeTest)

ObjetMock

Dans un test unitaire, les objets factices peuvent imiter le comportement d'objets complexes et réels (non factices). Ils sont donc utiles lorsqu'un objet réel est peu pratique ou impossible à inclure dans un test unitaire.

référence

Je suppose que tu aimes

Origine blog.csdn.net/lichukuan/article/details/126861893
conseillé
Classement