[JAVA] Quelles sont les règles de JUnit?

Qu'est-ce qu'une règle

Framework d'extension JUnit ajouté dans JUnit 4.7. Dans JUnit, il existe différents mécanismes pour extraire le traitement commun de la configuration des appareils Les règles sont un mécanisme qui rend plus facile et plus flexible l'extraction des processus courants.

Les caractéristiques sont les suivantes.

En raison des caractéristiques ci-dessus, les règles sont faciles à réutiliser et peuvent être décrites de manière déclarative. On peut dire que c'est un mécanisme qui peut être facilement étendu au moment de l'exécution du test.

Implémentation de la règle

Promesse de règles (déroutant)

  1. Doit être une classe d'implémentation de l'interface org.junit.rules.TestRule
  2. Ajoutez l'annotation org.junit.Rule ou org.junit.ClassRule Définir comme un champ public
  3. Créez une instance en même temps que la déclaration du champ Ou créez une instance avec le constructeur

Comment fonctionnent les règles

Le moment d'application de la règle diffère entre l'annotation de règle et l'annotation de règle de classe. L'annotation Règle est appliquée à chaque fois que la méthode de test est exécutée (identique à l'annotation Avant). L'annotation ClassRule est appliquée à chaque classe de test (identique à l'annotation BeforeClass).

Déclaration de plusieurs règles

Plusieurs règles peuvent être définies dans une classe de test. Cependant, si RuleChain (décrit plus loin) n'est pas utilisé, l'ordre d'exécution ne peut pas être contrôlé et il sera aléatoire.

Exemple d'implémentation de règle

RuleExampleTest.java


public class RuleExampleTest {
    @Rule
    public Timeout timeout = new TimeOut(100);
    @ClassRule
    public TestName testName = new TestName();

    @Test
public void Tests dont l'exécution peut prendre beaucoup de temps() throws Exception {
        doLongTask();
    }
}

Règles fournies par JUnit

TemporaryFolder: créer et libérer des dossiers temporaires

Remarque: un dossier temporaire est un dossier qui stocke temporairement les fichiers nécessaires.

Habituellement, lors de l'exécution de tests portant sur des systèmes de fichiers, chaque test Maintenez l'indépendance des tests en créant des dossiers en prétraitement et en les supprimant en post-traitement. Si vous définissez la classe org.junit.rules.TemporaryFolder en tant que règle, chaque fois que la règle est exécutée Étant donné que les dossiers sont créés et supprimés, il n'est pas nécessaire de mettre en œuvre ces processus.

public class TemporaryFolderExampleTest {
    @Rule
    public TemporaryFolder tmpFolder = new TemporaryFolder();

    @Test
public void mkFiles crée deux fichiers() throws Exception {
        File folder = tmpFolder.getRoot();
        TemporaryFolderExample.mkDefaultFiles(folder);
        String[] actualFiles = folder.list();
        Arrays.sort(actualFiles);
        assertThat(actualFiles.length, is(2));
        assertThat(actualFiles[0], is("UnitTest"));
        assertThat(actualFiles[1], is("readme.txt")); 
    }
}

TemporaryFolderExample.java


public class TemporaryFolderExample {

	public static void mkDefaultFiles(File folder) {
		String rootPath = folder.getPath();
		File file = new File(rootPath + "/UnitTest");
		File file2 = new File(rootPath + "/readme.txt");
		try {
			file.createNewFile();
			file2.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

Remarque: extension du dossier temporaire

La classe de dossier temporaire avant l'extension a été définie sur la propriété système Java "java.io.tmpdir" Il prépare et libère uniquement les ressources directement sous le dossier, mais le traitement peut être étendu en créant des sous-classes.

Puisque TemporaryFolder est une sous-classe de org.junit.rules.ExternalResource Remplace les méthodes avant et après. Comme ils sont appelés avant et après l'exécution du test, le traitement à effectuer à ce moment peut être étendu.

Ce qui suit crée une sous-classe directement sous le dossier temporaire avant l'exécution, Un exemple d'extension du nom de dossier créé après l'exécution vers la sortie vers la console.

SubTemporaryFolder.java


public class SubTemporaryFolder extends TemporaryFolder {

	//Sous-dossier
	public File srcFolder;
	public File testFolder;
	
	@Override
	protected void before() throws Throwable {
		//Dossier temporaire avant la méthode(Obligatoire)
		super.before();
		srcFolder = newFolder("src");
		testFolder = newFolder("test");
	}
	
	@Override
	protected void after() {
		//Dossier temporaire après la méthode(Obligatoire)
		super.after();
		System.out.println(srcFolder.getName());
		System.out.println(testFolder.getName());
	}
}

SubTemporaryFolderExampleTest.java


public class SubTemporaryFolderExampleTest {
	   @Rule
	    public SubTemporaryFolder tmpFolder = new SubTemporaryFolder();

	    @Test
public void mkFiles crée deux fichiers() throws Exception {
	        File folder = tmpFolder.getRoot();
	        File srcFolder = tmpFolder.srcFolder;
	        File testFolder = tmpFolder.testFolder;
	        assertThat(folder.list().length, is(2));
	        assertThat(srcFolder.list().length, is(0));
	        assertThat(testFolder.list().length, is(0));
	    }
}

ExternalResource: classe de base lors du traitement des ressources externes

La classe org.junit.rules.ExternalResource Une règle qui "prépare les ressources avant d'exécuter un test" et "libère les ressources après l'exécution d'un test". La classe ExternalResource étant une classe abstraite, implémentez une sous-classe lors de son utilisation.

Dans l'exemple, la sous-classe a été définie comme une classe imbriquée de la classe de test, Si elle est définie comme une classe indépendante, elle peut être utilisée par plusieurs classes de test.

python


public class ExternalResourceExampleTest() {
	
	@Rule
	public ServerResource resource = new ServerResource();

	static class ServerResource extends ExternalResource {
		ServerSocket server;
		
		@Override
		protected void before() throws Throwable {
			server = new ServerSocket(8080);
			server.accept();
		}
		
		@Override
		protected void after() {
			try {
				server.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	@Test
	public void test() {
		fail("Not yet implemented");
	}
}

Vérificateur: vérifier les conditions post-test

La classe org.junit.rules.Verifier est une règle qui valide les conditions post-test. Comme la classe ExternalResource, il s'agit d'une classe abstraite, créez donc une sous-classe et Remplacez et utilisez la méthode de vérification.

Des annotations après et après la classe ont été ajoutées pour vérifier la post-condition du test. Puisqu'il est également possible de le faire avec une méthode de post-traitement, le contenu de vérification est plus compliqué et je souhaite le faire sur plusieurs classes Dans ce cas, il est pratique d'utiliser correctement la classe Verifier.

L'ordre d'exécution est le suivant. Avant l'annotation → Tester l'annotation → Après l'annotation → vérifier la méthode

public class VerifierExampleTest {
    //Implémenté en tant que classe anonyme jetable
    @Rule
    public Verifier verifier = new Verifier() {
        protected void verify() throws Throwable {
            assertThat("value should be 0.", sut.value, is(0));
        }
    };
    VerifierExample sut;

    @Before
    public void setUp() throws Exception {
        sut = new VerifierExample();
    }

    @After
    public void tearDown() throws Exception {
        // do nothing.
    }

    @Test
Initialisez le résultat du calcul avec la méthode publique void clear et définissez-le sur 0.() throws Exception {
        sut.set(0);
        sut.add(140);
        sut.minus(5);
        assertThat(sut.getValue(), is(135));
        sut.clear();
    }
}

VerifierExample.java


public class VerifierExample {

	protected Integer value;

	public void set(int i) {
		value = i;
	}

	public void add(int i) {
		value += i;
	}

	public void minus(int i) {
		value -= i;
	}

	public Integer getValue() {
		return value;
	}

	public void clear() {
		value = 0;
	}
}

ErrorCollector: personnaliser la gestion des exceptions lors des tests

Normalement, le traitement de la méthode de test dans JUnit se termine lorsqu'une erreur se produit. Cependant, si vous utilisez la classe org.junit.rules.ErrorCollector après avoir exécuté le test jusqu'à la fin, Produit des informations sur les erreurs collectivement.

public class ItemInfoTest {
	
	@Rule
	public ErrorCollector errCollector = new ErrorCollector();

	@Test
public void Vérification lors de l'application des règles() throws Exception {
		ItemInfo itemInfo = new ItemInfo();
		errCollector.checkThat(itemInfo, is(nullValue())); /*Où l'erreur s'est produite*/
		errCollector.checkThat(itemInfo.getId(), is(""));
		errCollector.checkThat(itemInfo.getName(), is(not(""))); /*Où l'erreur s'est produite*/
		errCollector.checkThat(itemInfo.getStockNum(), is(0));
	}
	
	@Test
public void Vérification normale() throws Exception {
		ItemInfo itemInfo = new ItemInfo();
		assertThat(itemInfo, is(nullValue())); /*Où l'erreur s'est produite*/
		assertThat(itemInfo.getId(), is(""));
		assertThat(itemInfo.getName(), is(not(""))); /*Où l'erreur s'est produite*/
		assertThat(itemInfo.getStockNum(), is(0));
	}

}

ItemInfo.java


public class ItemInfo {
	
	private String id;
	
	private String name;
	
	private int stockNum;
	
	public ItemInfo() {
		this.id = "";
		this.name = "";
		this.stockNum = 0;
	}

/*Ci-dessous, la méthode Getter et Setter de chaque membre*/

}

Rapport d'erreur


~ Vérification lors de l'application des règles ~

Expected: is null
     but: was <com.example.junit.rules.errcollect.ItemInfo@506c589e>

java.lang.AssertionError: 
Expected: is not ""
     but: was ""

~ Vérification normale ~

Expected: is null
     but: was <com.example.junit.rules.errcollect.ItemInfo@1698c449>

ExpectedException: examinez l'exception en détail

La classe org.junit.rules.ExpectedException valide l'exception levée C'est une règle qui fournit un mécanisme pour le faire simplement. Afin de comparer la méthode d'implémentation, le cas où la règle n'est pas utilisée et le cas où la règle est utilisée sont comparés ci-dessous.

public class ExpectExceptionExampleTest {
	
	@Rule
	public ExpectedException exException = ExpectedException.none();
	
	@Test
public void Valider les messages d'exception à l'aide de règles() throws Exception {
		exException.expect(ArithmeticException.class);
		exException.expectMessage(containsString("by zero"));
		int result = 1 / 0;
		System.out.println(result);
	}

	@Test
public void Valide les messages d'exception de manière standard() throws Exception {
		try {
			int result = 1 / 0;
			System.out.println(result);
			//Détecter quand aucune exception ne se produit
			fail("Pas exception");
		} catch (ArithmeticException e) {
			assertThat(e.getMessage(), is(containsString("by zero")));
		}
	}
}

Timeout: contrôler le timeout

Une règle qui vous permet de définir l'heure jusqu'à l'expiration du délai, tout comme la lecture. Vous pouvez également définir le délai d'expiration en passant une valeur à l'attribut timeout de l'annotation Test, Lors du réglage commun à toutes les méthodes de test de la classe de test La description peut être combinée en un seul endroit à l'aide de la classe Timeout.

public class TimeoutExampleTest {
	@Rule
	public Timeout timeout = new Timeout(1000);

	@Test
	public void sleep1() throws InterruptedException {
		while(true) {
		}
	}
	
	@Test
	public void sleep2() throws InterruptedException {
		while(true) {
		}
	}
}

TestWatcher: enregistrer lorsque le test est exécuté

La classe org.junit.rules.TestWatcher peut être utilisée avec les journaux C'est une règle qui permet de surveiller (suivre) l'état d'exécution du test. TestWatcher est une classe abstraite, utilisez-la donc en remplaçant les méthodes des sous-classes.

L'ordre d'exécution de TestWatcher lorsque le test réussit et échoue est le suivant.

[Au moment du succès] starting → succeeded → finished

[Au moment de l'échec] starting → failed → finished

public class TestWatcherExampleTest {
	
	@Rule
	public TestWatcher testWatcher = new TestWatcher() {
		
		@Override
		protected void starting(Description desc) {
                    Logger.getAnonymousLogger()
                        .info("start: " + desc.getMethodName());
		}
		
		@Override
		protected void succeeded(Description desc) {
                    Logger.getAnonymousLogger()
                        .info("succeeded: " + desc.getMethodName());
		}
		
		@Override
		protected void failed(Throwable e, Description desc) {
                    Logger.getAnonymousLogger()
                        .log(Level.WARNING, "failed: " + desc.getMethodName(), e);
		}
		
		@Override
		protected void finished(Description desc) {
			Logger.getAnonymousLogger()
                    .info("finished: " + desc.getMethodName());
		}
	};

	@Test
public void Test réussi() throws Exception {
	}
	
	@Test
test public void qui échoue() throws Exception {
		fail("NG");
	}
}

Sortie de journal


4 23, 2020 7:11:08 h 00 com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 starting
information: start:Tests qui échouent
4 23, 2020 7:11:08 h 00 com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 failed
avertissement: failed:Tests qui échouent
java.lang.AssertionError: NG
	at org.junit.Assert.fail(Assert.java:88)
	at com.example.junit.rules.testwatcher.TestWatcherExampleTest.Tests qui échouent(TestWatcherExampleTest.java:45)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

4 23, 2020 7:11:08 h 00 com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 finished
information: finished:Tests qui échouent
4 23, 2020 7:11:08 h 00 com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 starting
information: start:Test réussi
4 23, 2020 7:11:08 h 00 com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 succeeded
information: succeeded:Test réussi
4 23, 2020 7:11:08 h 00 com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 finished
information: finished:Test réussi

TestName: fait référence au nom de la méthode de test en cours d'exécution

La classe org.junit.rules.TestName est Une règle pour obtenir le nom de la méthode en cours d'exécution dans la méthode de test. En pouvant obtenir le nom de la méthode dans la méthode de test, le nom de la méthode et la ressource externe Il existe différentes manières de l'utiliser, par exemple en associant le nom du fichier.

public class TestNameExampleTest {
    @Rule
    public TestName testName = new TestName();

    @Test
nom de la méthode de test public void() throws Exception {
        fail(testName.getMethodName() + " is unimplements yet.");
    }
}

Créer des règles personnalisées

Pour créer une règle personnalisée

  1. Créez une sous-classe d'une classe abstraite déjà implémentée (telle que la classe ExternalResource)
  2. Créez une classe qui implémente l'interface TestRule

Il existe deux méthodes.

Interface TestRule

Les méthodes suivantes sont définies dans l'interface org.junit.rules.TestRule.

Statement apply(Statement base, Description description);

Objet de déclaration

La classe org.junit.runners.model.Statement est une classe qui contrôle l'exécution des tests. Le test est exécuté lorsque la méthode Statement.evaluate est appelée. L'objet Statement passé en tant qu'argument à la méthode apply se trouve dans la méthode d'évaluation. Les tests sont configurés pour s'exécuter dans l'ordre suivant:

  1. Création d'une instance de la classe de test
  2. Exécution de la méthode avec annotation Avant (pré-traitement)
  3. Exécution de la méthode d'essai
  4. Exécution de la méthode avec annotation After (post-traitement)

Objet de description

La classe org.junit.runner.Description est une classe qui contient des méta-informations pour les cas de test. Vous pouvez obtenir des informations telles que la classe de test, le nom de la méthode de test et l'annotation attribuée.

Modèle de mise en œuvre

Une implémentation courante d'une règle se trouve dans l'objet Statement de l'argument Créez un objet proxy (objet proxy) et renvoyez-le comme valeur de retour.

nom de règle personnalisé de classe abstraite publique implémente TestRule{

	@Override
	public Statement apply(Statement base, Description description) {
		return new Statement() {
			@Override
			public void evaluate() throws Throwable {
				//Vous pouvez appeler votre propre prétraitement comme pré et post-traitement,
				customedBySubClazz();
				//Obtenir des méta-informations de test et une branche conditionnelle
				if (description.getMethodName().equals("Nom de la méthode d'essai applicable")) {
					//Selon le résultat du jugement, la méthode d'évaluation originale peut être exécutée ou non.
					base.evaluate();
				} else {
					fail("La méthode d'essai est différente");
				}

			}
		};
	}
	//Méthode abstraite pour implémenter un traitement unique lors de la définition d'une sous-classe
	protected abstract void customedBySubClazz() throws Throwable;
}

Règles personnalisées pour vérifier les conditions préalables

Créez une règle personnalisée pour vérifier les conditions préalables du test. La différence par rapport au contrôle de la précondition par la méthode avec l'annotation Avant est Les extensions peuvent être fournies plus indépendamment de la classe de test. Accès facile aux méta-informations. Il y a une telle chose. Pour l'implémentation, reportez-vous à l'implémentation de la classe Verifier.

Classe de règles personnalisées


public abstract class PreProcess implements TestRule {

	@Override
	public Statement apply(Statement base, Description description) {
		return new Statement() {
			@Override
			public void evaluate() throws Throwable {
				//Prétraitement exclusif
				verify();
				//Méthode d'évaluation originale
				base.evaluate();
			}
		};
	}

	//Implémentez votre propre prétraitement lors de la définition des sous-classes
	protected abstract void verify() throws Throwable;
}

Classe de test avec PreProcess appliqué à la règle


public class PreProcessExampleTest {
	
	@Rule
	public PreProcess preProcess = new PreProcess() {
		@Override
		protected void verify() throws Throwable {
			LocalDate now = LocalDate.now();
			LocalDate limitDate = LocalDate.of(2015, 4, 1);
			if (now.isAfter(limitDate)) {
				throw new AssertionError();
			}
		}
	};

	@Test
public void Tests qui ne s'exécutent pas() {
		assertThat(1, is(1));
	}
}

Règles personnalisées pour les tests dépendant du système d'exploitation

Créez des règles personnalisées pour les tests dépendants du système d'exploitation. Lors de l'évaluation de l'objet proxy, déterminez le système d'exploitation de l'environnement d'exécution et Uniquement s'il correspond au système d'exploitation attendu (système d'exploitation spécifié par l'annotation RunOn de l'implémentation d'origine) Appelez la méthode d'évaluation d'origine.

Créez votre propre annotation pour configurer le système d'exploitation pour exécuter le test

Pour plus de détails sur les méta-informations utilisées lors de la création de l'annotation, voir Voir Articles publiés sur TECHSCORE.

Grosso modo

@Retention(RetentionPolicy.RUNTIME)→ Peut être consulté lors de l'exécution du test JUnit



#### **`@Target({ElementType.METHOD})→ C'est une annotation donnée à la méthode`**
```METHOD})→ C'est une annotation donnée à la méthode

 Se sentir comme ça.


#### **`Annotation d'implémentation propriétaire`**
```java

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface RunOn {
	public enum OS {
		WINDOWS, MAC, LINUX
	}
	public OS value();
}

Implémentation de règles personnalisées

Dans la règle personnalisée, avec le système d'exploitation obtenu à partir de l'annotation RunOn Déterminez si le système d'exploitation de l'environnement d'exécution obtenu à partir des propriétés du système Java correspond, S'ils correspondent, appelez la méthode d'évaluation d'origine et Mettez en œuvre le processus consistant à ne rien faire s'ils ne correspondent pas.

public class OSDepend implements TestRule {
	
	@Override
	public Statement apply(Statement base, Description desc) {
		return new Statement() {
			@Override
			public void evaluate() throws Throwable {
				//Obtenez l'annotation donnée à la méthode à partir de Description
				RunOn env = desc.getAnnotation(RunOn.class);
				//Déterminer si le système d'exploitation spécifié dans l'annotation correspond au système d'exploitation de l'environnement d'exécution
				if (env == null || canEvaluate(env.value())) {
					base.evaluate();
				} else {
					// don't evaluate
				}
			}
			
			private boolean canEvaluate(OS os) {
				/*Obtenez le système d'exploitation de l'environnement d'exécution à partir des propriétés système
Renvoie true s'il correspond au système d'exploitation spécifié dans l'annotation RunOn*/
				String osName = System.getProperty("os.name");
				if (osName == null) {
					return false;
				}
				if (os == OS.WINDOWS && osName.startsWith("Windows")) {
					return true;
				}
				if (os == OS.MAC && osName.startsWith("Mac OS X")) {
					return true;
				}
				if (os == OS.LINUX && osName.startsWith("Linux")) {
					return true;
				}
				return false;
			}
		};
	}
}

Classe de test pour les tests dépendants du système d'exploitation

Si vous exécutez la classe de test suivante, deux tests seront effectués, Seul Mac a une sortie console (car mon environnement est Mac) Vous pouvez voir que le scénario de test dans l'environnement Windows n'a pas été exécuté.

public class OSDependExampleTest {
	@Rule
	public OSDepend osDepend = new OSDepend();

	@Test
	//Annotation qui définit Enum pour déterminer le système d'exploitation
	@RunOn(OS.WINDOWS)
public void Tests exécutés uniquement dans un environnement Windows() {
		System.out.println("test: onlyWindows");
		assertThat(File.separator, is("¥¥"));
	}

	@Test
	@RunOn(OS.MAC)
public void Tests exécutés uniquement dans un environnement Mac() {
		System.out.println("test: onlyMac");
		assertThat(File.separator, is("/"));
	}
}

↓ résultat de l'exécution JUnit スクリーンショット 2020-04-24 10.44.07.png

Sortie de la console


test: onlyMac

Contrôle de l'ordre d'exécution des règles par RuleChain

Lors du contrôle de ressources externes à l'aide de règles, il existe des cas où il est nécessaire de spécifier l'ordre d'exécution. Par exemple, s'il existe un scénario de test qui relie le serveur AP et le serveur DB, L'ordre d'exécution doit être démarrage du serveur de base de données → démarrage du serveur AP.

Dans ce cas, utilisez la classe org.junit.rules.RuleChain pour Vous pouvez contrôler l'ordre d'exécution sous la forme de ** exécutions de règles de chaînage **. (Modèle de chaîne de responsabilité: un type de modèle de conception)

Exemple d'implémentation RuleChain

Les méthodes suivantes sont implémentées dans la classe RuleChain.

static rulechain outerrule(testrule outerrule) Spécifiez une règle qui s'initialise en premier et se termine ensuite

rulechain around(testrule enclosedrule) Spécifiez une règle qui s'initialise plus tard et se termine en premier

S'il s'agit d'une lettre, elle n'est pas arrivée rapidement, elle est donc illustrée. スクリーンショット 2020-04-24 11.11.05.png

public class RuleChainExampleTest {
    @Rule
    public RuleChain ruleChain = RuleChain
                                    .outerRule(new PreRule())
                                    .around(new PostRule());

    @Test
test du vide public() throws Exception {
    }
}

class PreRule extends ExternalResource {
    @Override
    protected void before() throws Throwable {
        System.out.println("1 start: PreRule");
    }

    @Override
    protected void after()  {
        System.out.println("4 finish: PreRule");
    }
}

class PostRule extends ExternalResource {
    @Override
    protected void before() throws Throwable {
        System.out.println("2 start: PostRule");
    }

    @Override
    protected void after()  {
        System.out.println("3 finish: PostRule");
    }
}

Sortie de la console


1 start: PreRule
2 start: PostRule
3 finish: PostRule
4 finish: PreRule

Application de RuleChain par ClassRule

Le démarrage et l'arrêt du serveur étant un processus lourd, des problèmes de test lents se produisent à mesure que le nombre de cas de test augmente. Par conséquent, si vous n'avez pas besoin de contrôle spécial au démarrage et à l'arrêt, utilisez l'annotation ClassRule. Il est possible d'économiser des ressources en démarrant et en arrêtant le serveur pour chaque classe de test.

Les références

Cet article a été rédigé en référence aux informations suivantes.

Recommended Posts

Quelles sont les règles de JUnit?
Que faire lorsque les modifications du servlet ne sont pas reflétées
Quelle est la méthode principale en Java?
Refactoring dans JUnit
Ce que j'ai appris en Java (partie 2) Que sont les variables?
Quels sont les avantages de DI et de Thymeleaf?
Que faire si les modifications ne sont pas reflétées dans le fichier manifeste JAR
La fraction n'est-elle pas mauvaise en programmation? L'histoire.
Résumé personnel des types souvent utilisés dans JUnit 4
Ce que je suis tombé sur le test ActiveModel :: Serializer
Et si les résultats de sum et inject (: +) sont différents?
Le cas où @Autowired n'a pas pu être utilisé dans JUnit5
Identifiez les threads du processus Java qui gaspillent du processeur
Quelle est la représentation de la connaissance du domaine dans le modèle [DDD]?
Le saut de ligne du texte saisi n'est pas affiché dans la vue
Si les éléments du sous-module ne sont pas trouvés dans Play Framework
Vérifiez si les transactions Ethereum ne sont pas incluses dans le bloc
À propos des méthodes de validation dans JUnit
[Comprendre en 3 minutes] Qu'est-ce que l'héritage Ruby? Seuls les points principaux sont expliqués de manière facile à comprendre!
[rails] Que sont les paramètres forts?
Qu'est-ce que la classe BufferedReader?
Tester les méthodes privées dans JUnit
[Variables environnementales] rails Quelles sont les variables environnementales?
Quelle révolution se produit dans la programmation
Tester les méthodes privées dans JUnit
Quelles sont les variables pratiquement finales?
config.ru Que faites-vous?
[JUnit] Tester l'exception levée
A quoi sert le constructeur?
Que sont les vulnérabilités d'attribution de masse?
Image JavaFX-Load en arrière-plan
Que sont les métriques Java? _Memo_20200818
Quelle est la méthode d'initialisation?
Ce que les débutants du développement Android ont fait avant de publier l'application dans 2 semaines
Que faire si j'écris une clause finally dans la syntaxe try-with-resources?
[Spring Boot] Simulez le contenu câblé automatiquement en dehors de la portée [JUnit 5]
Le problème de la réorganisation arbitraire des attributs XML dans Android Studio
Ce que j'ai fait lors de la migration de la série Spring Boot 1.4 vers la série 2.0
Que faire lorsque Cloud 9 est plein dans le didacticiel Rails
Qu'est-ce que @Override ou @SuppressWarnings ("SleepWhileInLoop") devant la fonction? ?? ??
Ce que j'ai fait lors de la migration de la série Spring Boot 1.5 vers la série 2.0
Juger si les chaînes de caractères à comparer sont les mêmes en Java
Qu'est-il arrivé aux modifications typiques d'Apache Wicket 8?
Que faire si vous oubliez votre mot de passe root sur CentOS7
Découvrez ce que font de nombreux threads à partir des résultats de jstack