[JAVA] Was sind die Regeln in JUnit?

Was ist eine Regel

JUnit-Erweiterungsframework in JUnit 4.7 hinzugefügt. In JUnit gibt es verschiedene Mechanismen zum Extrahieren der allgemeinen Verarbeitung des Geräte-Setups. Regeln sind ein Mechanismus, der es einfacher und flexibler macht, gemeinsame Prozesse zu extrahieren.

Die Funktionen sind wie folgt.

Aufgrund der oben genannten Eigenschaften sind die Regeln leicht wiederzuverwenden und können deklarativ beschrieben werden. Es kann gesagt werden, dass es sich um einen Mechanismus handelt, der zum Zeitpunkt der Testausführung leicht erweitert werden kann.

Regelimplementierung

Versprechen von Regeln (verwirrend)

  1. Muss eine Implementierungsklasse der Schnittstelle org.junit.rules.TestRule sein
  2. Fügen Sie die Annotation org.junit.Rule oder org.junit.ClassRule hinzu Als öffentliches Feld definieren
  3. Erstellen Sie gleichzeitig mit der Deklaration des Felds eine Instanz Oder erstellen Sie eine Instanz mit dem Konstruktor

Wie die Regeln funktionieren

Das Timing der Regelanwendung unterscheidet sich zwischen der Regelanmerkung und der Klassenregelanmerkung. Die Regelanmerkung wird jedes Mal angewendet, wenn die Testmethode ausgeführt wird (wie die Voranmerkung). Die ClassRule-Annotation wird auf jede Testklasse angewendet (wie die BeforeClass-Annotation).

Erklärung mehrerer Regeln

In einer Testklasse können mehrere Regeln definiert werden. Wenn jedoch RuleChain (später beschrieben) nicht verwendet wird, kann die Ausführungsreihenfolge nicht gesteuert werden und ist zufällig.

Beispiel für die Regelimplementierung

RuleExampleTest.java


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

    @Test
public void Tests, deren Ausführung lange dauern kann() throws Exception {
        doLongTask();
    }
}

Von JUnit bereitgestellte Regeln

Temporärer Ordner: Erstellen und freigeben Sie temporäre Ordner

Hinweis: Ein temporärer Ordner ist ein Ordner, in dem die erforderlichen Dateien vorübergehend gespeichert werden.

Wenn Sie Tests ausführen, die sich mit Dateisystemen befassen, wird normalerweise jeder Test ausgeführt Bewahren Sie die Testunabhängigkeit, indem Sie Ordner in der Vorverarbeitung erstellen und in der Nachbearbeitung löschen. Wenn Sie die Klasse org.junit.rules.TemporaryFolder als Regel definieren, wird die Regel jedes Mal ausgeführt Da Ordner erstellt und gelöscht werden, müssen diese Prozesse nicht implementiert werden.

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

    @Test
public void mkFiles erstellt zwei Dateien() 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();
		}
		
	}

}

Hinweis: Erweiterung des temporären Ordners

Die Klasse "Temporärer Ordner" vor der Erweiterung wurde auf die Java-Systemeigenschaft "java.io.tmpdir" festgelegt. Es werden nur die Ressourcen direkt unter dem Ordner vorbereitet und freigegeben. Die Verarbeitung kann jedoch durch Erstellen von Unterklassen erweitert werden.

Da TemporaryFolder eine Unterklasse von org.junit.rules.ExternalResource ist Überschreibt die Vorher- und Nachher-Methoden. Da sie vor und nach der Ausführung des Tests aufgerufen werden, kann die zu diesem Zeitpunkt auszuführende Verarbeitung erweitert werden.

Im Folgenden wird vor der Ausführung eine Unterklasse direkt unter dem temporären Ordner erstellt. Ein Beispiel für die Erweiterung des nach der Ausführung erstellten Ordnernamens für die Ausgabe an die Konsole.

SubTemporaryFolder.java


public class SubTemporaryFolder extends TemporaryFolder {

	//Unterordner
	public File srcFolder;
	public File testFolder;
	
	@Override
	protected void before() throws Throwable {
		//Temporärer Ordner vor der Methode(Verpflichtend)
		super.before();
		srcFolder = newFolder("src");
		testFolder = newFolder("test");
	}
	
	@Override
	protected void after() {
		//Temporärer Ordner nach Methode(Verpflichtend)
		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 erstellt zwei Dateien() 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: Basisklasse beim Umgang mit externen Ressourcen

Die org.junit.rules.ExternalResource-Klasse Eine Regel, die "Ressourcen vor dem Ausführen eines Tests vorbereitet" und "Ressourcen nach dem Ausführen eines Tests freigibt". Da die ExternalResource-Klasse eine abstrakte Klasse ist, implementieren Sie bei Verwendung eine Unterklasse.

Im Beispiel wurde die Unterklasse als verschachtelte Klasse der Testklasse definiert. Wenn dies als unabhängige Klasse definiert ist, kann es von mehreren Testklassen verwendet werden.

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");
	}
}

Prüfer: Überprüfen Sie die Bedingungen nach dem Test

Die org.junit.rules.Verifier-Klasse ist eine Regel, die die Bedingungen nach dem Test überprüft. Wie die ExternalResource-Klasse handelt es sich um eine abstrakte Klasse. Erstellen Sie daher eine Unterklasse und Überschreiben und verwenden Sie die Überprüfungsmethode.

Anmerkungen nach und nach der Klasse wurden hinzugefügt, um die Nachbedingung des Tests zu überprüfen. Da dies auch mit einer Nachbearbeitungsmethode möglich ist, ist der Überprüfungsinhalt komplizierter und ich möchte ihn über mehrere Klassen hinweg durchführen In diesem Fall ist es zweckmäßig, die Verifier-Klasse ordnungsgemäß zu verwenden.

Die Ausführungsreihenfolge ist wie folgt. Vor der Annotation → Annotation testen → Nach der Annotation → Methode überprüfen

public class VerifierExampleTest {
    //Implementiert als anonyme Einwegklasse
    @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
Initialisieren Sie das Berechnungsergebnis mit der Methode public void clear und setzen Sie es auf 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: Passen Sie die Behandlung von Ausnahmen während des Tests an

Normalerweise endet die Verarbeitung der Testmethode in JUnit, wenn ein Fehler auftritt. Wenn Sie jedoch die org.junit.rules.ErrorCollector-Klasse verwenden, nachdem Sie den Test bis zum Ende ausgeführt haben, Gibt Informationen zu Fehlern gemeinsam aus.

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

	@Test
public void Überprüfung bei der Anwendung von Regeln() throws Exception {
		ItemInfo itemInfo = new ItemInfo();
		errCollector.checkThat(itemInfo, is(nullValue())); /*Wo der Fehler aufgetreten ist*/
		errCollector.checkThat(itemInfo.getId(), is(""));
		errCollector.checkThat(itemInfo.getName(), is(not(""))); /*Wo der Fehler aufgetreten ist*/
		errCollector.checkThat(itemInfo.getStockNum(), is(0));
	}
	
	@Test
public void Normale Überprüfung() throws Exception {
		ItemInfo itemInfo = new ItemInfo();
		assertThat(itemInfo, is(nullValue())); /*Wo der Fehler aufgetreten ist*/
		assertThat(itemInfo.getId(), is(""));
		assertThat(itemInfo.getName(), is(not(""))); /*Wo der Fehler aufgetreten ist*/
		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;
	}

/*Unten die Getter- und Setter-Methode jedes Mitglieds*/

}

Fehlermeldung


~ Überprüfung bei der Anwendung von Regeln ~

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

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

~ Normale Überprüfung ~

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

ExpectedException: Untersuchen Sie die Ausnahme im Detail

Die Klasse org.junit.rules.ExpectedException überprüft die ausgelöste Ausnahme Es ist eine Regel, die einen Mechanismus bietet, um dies einfach zu tun. Um die Implementierungsmethode zu vergleichen, werden im Folgenden der Fall verglichen, in dem die Regel nicht verwendet wird, und der Fall, in dem die Regel verwendet wird.

public class ExpectExceptionExampleTest {
	
	@Rule
	public ExpectedException exException = ExpectedException.none();
	
	@Test
public void Überprüfen Sie Ausnahmemeldungen anhand von Regeln() throws Exception {
		exException.expect(ArithmeticException.class);
		exException.expectMessage(containsString("by zero"));
		int result = 1 / 0;
		System.out.println(result);
	}

	@Test
public void Überprüfen Sie Ausnahmemeldungen auf standardmäßige Weise() throws Exception {
		try {
			int result = 1 / 0;
			System.out.println(result);
			//Erkennen, wenn keine Ausnahme auftritt
			fail("Keine Ausnahmen");
		} catch (ArithmeticException e) {
			assertThat(e.getMessage(), is(containsString("by zero")));
		}
	}
}

Zeitüberschreitung: Steuern Sie die Zeitüberschreitung

Eine Regel, mit der Sie die Zeit bis zum Timeout genau wie beim Lesen einstellen können. Sie können das Zeitlimit auch festlegen, indem Sie einen Wert an das Zeitlimitattribut der Testanmerkung übergeben. Bei der Einstellung, die allen Testmethoden in der Testklasse gemeinsam ist Die Beschreibung kann mithilfe der Timeout-Klasse an einer Stelle kombiniert werden.

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: Aufzeichnen, wann der Test ausgeführt wird

Die org.junit.rules.TestWatcher-Klasse kann in Verbindung mit Protokollen verwendet werden Es ist eine Regel, die den Ausführungsstatus des Tests überwachen (befolgen) kann. TestWatcher ist eine abstrakte Klasse. Verwenden Sie sie daher, indem Sie Methoden in Unterklassen überschreiben.

Die Ausführungsreihenfolge von TestWatcher, wenn der Test erfolgreich ist und fehlschlägt, lautet wie folgt.

[Zum Zeitpunkt des Erfolgs] starting → succeeded → finished

[Zum Zeitpunkt des Scheiterns] 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 Erfolgreicher Test() throws Exception {
	}
	
	@Test
öffentlicher Leertest, der fehlschlägt() throws Exception {
		fail("NG");
	}
}

Protokollausgabe


4 23, 2020 7:11:20 Uhr com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 starting
Information: start:Tests, die fehlschlagen
4 23, 2020 7:11:20 Uhr com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 failed
Warnung: failed:Tests, die fehlschlagen
java.lang.AssertionError: NG
	at org.junit.Assert.fail(Assert.java:88)
	at com.example.junit.rules.testwatcher.TestWatcherExampleTest.Tests, die fehlschlagen(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:20 Uhr com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 finished
Information: finished:Tests, die fehlschlagen
4 23, 2020 7:11:20 Uhr com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 starting
Information: start:Erfolgreicher Test
4 23, 2020 7:11:20 Uhr com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 succeeded
Information: succeeded:Erfolgreicher Test
4 23, 2020 7:11:20 Uhr com.example.junit.rules.testwatcher.TestWatcherExampleTest$1 finished
Information: finished:Erfolgreicher Test

Testname: Bezieht sich auf den Namen der ausgeführten Testmethode

Die Klasse org.junit.rules.TestName lautet Eine Regel, um den Namen der Methode abzurufen, die in der Testmethode ausgeführt wird. Indem Sie den Methodennamen in der Testmethode, den Methodennamen und die externe Ressource abrufen können Es gibt verschiedene Verwendungsmöglichkeiten, z. B. das Verknüpfen des Dateinamens.

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

    @Test
Name der öffentlichen ungültigen Testmethode() throws Exception {
        fail(testName.getMethodName() + " is unimplements yet.");
    }
}

Erstellen Sie benutzerdefinierte Regeln

So erstellen Sie eine benutzerdefinierte Regel

  1. Erstellen Sie eine Unterklasse einer bereits implementierten abstrakten Klasse (z. B. der ExternalResource-Klasse).
  2. Erstellen Sie eine Klasse, die die TestRule-Schnittstelle implementiert

Es gibt zwei Methoden.

TestRule-Schnittstelle

Die folgenden Methoden sind in der Schnittstelle org.junit.rules.TestRule definiert.

Statement apply(Statement base, Description description);

Anweisungsobjekt

Die Klasse org.junit.runners.model.Statement ist eine Klasse, die die Ausführung von Tests steuert. Der Test wird ausgeführt, wenn die Statement.evaluate-Methode aufgerufen wird. Das als Argument an die apply-Methode übergebene Statement-Objekt befindet sich in der evalu-Methode. Die Tests sind so eingerichtet, dass sie in der folgenden Reihenfolge ausgeführt werden:

  1. Erstellen einer Instanz der Testklasse
  2. Ausführung der Methode mit Vor Annotation (Vorverarbeitung)
  3. Ausführung der Testmethode
  4. Ausführung der Methode mit After Annotation (Nachbearbeitung)

Beschreibung Objekt

Die org.junit.runner.Description-Klasse ist eine Klasse, die Metainformationen für Testfälle enthält. Sie können Informationen wie Testklasse, Name der Testmethode und gegebene Anmerkungen erhalten.

Implementierungsvorlage

Eine übliche Implementierung einer Regel befindet sich im Statement-Objekt des Arguments Erstellen Sie ein Proxy-Objekt (Proxy-Objekt) und geben Sie es als Rückgabewert zurück.

Der benutzerdefinierte Regelname der öffentlichen abstrakten Klasse implementiert TestRule{

	@Override
	public Statement apply(Statement base, Description description) {
		return new Statement() {
			@Override
			public void evaluate() throws Throwable {
				//Sie können Ihre eigene Vorverarbeitung als Vor- und Nachbearbeitung bezeichnen.
				customedBySubClazz();
				//Holen Sie sich Test-Metainformationen und bedingte Verzweigungen
				if (description.getMethodName().equals("Anwendbarer Name der Testmethode")) {
					//Abhängig vom Beurteilungsergebnis kann die ursprüngliche Bewertungsmethode ausgeführt werden oder nicht.
					base.evaluate();
				} else {
					fail("Die Testmethode ist anders");
				}

			}
		};
	}
	//Abstrakte Methode zur Implementierung einer eindeutigen Verarbeitung beim Definieren einer Unterklasse
	protected abstract void customedBySubClazz() throws Throwable;
}

Benutzerdefinierte Regeln zur Überprüfung der Voraussetzungen

Erstellen Sie eine benutzerdefinierte Regel, um die Testvoraussetzungen zu überprüfen. Der Unterschied zur Vorbedingungsprüfung durch die Methode mit der Annotation Before ist Erweiterungen können unabhängiger von der Testklasse bereitgestellt werden. Einfacher Zugriff auf Metainformationen. Da ist so etwas. Informationen zur Implementierung finden Sie in der Implementierung der Verifier-Klasse.

Benutzerdefinierte Regelklasse


public abstract class PreProcess implements TestRule {

	@Override
	public Statement apply(Statement base, Description description) {
		return new Statement() {
			@Override
			public void evaluate() throws Throwable {
				//Proprietäre Vorverarbeitung
				verify();
				//Ursprüngliche Bewertungsmethode
				base.evaluate();
			}
		};
	}

	//Implementieren Sie Ihre eigene Vorverarbeitung, wenn Sie Unterklassen definieren
	protected abstract void verify() throws Throwable;
}

Testklasse mit PreProcess, die auf die Regel angewendet wird


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, die nicht ausgeführt werden() {
		assertThat(1, is(1));
	}
}

Benutzerdefinierte Regeln für betriebssystemabhängige Tests

Erstellen Sie benutzerdefinierte Regeln für betriebssystemabhängige Tests. Bestimmen Sie zum Auswerten des Proxy-Objekts das Betriebssystem der Ausführungsumgebung und Nur wenn es mit dem erwarteten Betriebssystem übereinstimmt (Betriebssystem, das in der RunOn-Annotation der ursprünglichen Implementierung angegeben ist) Rufen Sie die ursprüngliche Auswertungsmethode auf.

Erstellen Sie Ihre eigene Anmerkung, um das Betriebssystem für die Ausführung des Tests festzulegen

Einzelheiten zu den Metainformationen, die beim Erstellen der Anmerkung verwendet werden, finden Sie unter Siehe Artikel auf TECHSCORE.

Grob gesagt

@Retention(RetentionPolicy.RUNTIME)→ Kann bei der Ausführung des JUnit-Tests verwendet werden



#### **`@Target({ElementType.METHOD})→ Es handelt sich um eine Anmerkung zur Methode`**
```METHOD})→ Es handelt sich um eine Anmerkung zur Methode

 Ich fühle mich so.


#### **`Eigene Implementierungsanmerkung`**
```java

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

Implementierung von benutzerdefinierten Regeln

In der benutzerdefinierten Regel mit dem aus der RunOn-Annotation erhaltenen Betriebssystem Stellen Sie fest, ob das aus den Java-Systemeigenschaften erhaltene Betriebssystem der Ausführungsumgebung übereinstimmt. Wenn sie übereinstimmen, rufen Sie die ursprüngliche Auswertungsmethode und auf Implementieren Sie den Prozess, nichts zu tun, wenn sie nicht übereinstimmen.

public class OSDepend implements TestRule {
	
	@Override
	public Statement apply(Statement base, Description desc) {
		return new Statement() {
			@Override
			public void evaluate() throws Throwable {
				//Rufen Sie die der Methode gegebene Anmerkung aus der Beschreibung ab
				RunOn env = desc.getAnnotation(RunOn.class);
				//Stellen Sie fest, ob das in der Anmerkung angegebene Betriebssystem mit dem Betriebssystem der Ausführungsumgebung übereinstimmt
				if (env == null || canEvaluate(env.value())) {
					base.evaluate();
				} else {
					// don't evaluate
				}
			}
			
			private boolean canEvaluate(OS os) {
				/*Rufen Sie das Betriebssystem der Ausführungsumgebung aus den Systemeigenschaften ab
Gibt true zurück, wenn es mit dem in der RunOn-Annotation angegebenen Betriebssystem übereinstimmt*/
				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;
			}
		};
	}
}

Testklasse für betriebssystemabhängige Tests

Wenn Sie die folgende Testklasse ausführen, werden zwei Tests durchgeführt: Nur Mac hat Konsolenausgabe (weil meine Umgebung Mac ist) Sie können sehen, dass der Testfall in der Windows-Umgebung nicht ausgeführt wurde.

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

	@Test
	//Anmerkung, die Enum definiert, um das Betriebssystem zu bestimmen
	@RunOn(OS.WINDOWS)
public void Tests, die nur in einer Windows-Umgebung ausgeführt werden() {
		System.out.println("test: onlyWindows");
		assertThat(File.separator, is("¥¥"));
	}

	@Test
	@RunOn(OS.MAC)
public void Tests, die nur in einer Mac-Umgebung ausgeführt werden() {
		System.out.println("test: onlyMac");
		assertThat(File.separator, is("/"));
	}
}

↓ JUnit-Ausführungsergebnis スクリーンショット 2020-04-24 10.44.07.png

Konsolenausgabe


test: onlyMac

Steuern der Reihenfolge der Regelausführung durch RuleChain

Bei der Steuerung externer Ressourcen mithilfe von Regeln muss in bestimmten Fällen die Ausführungsreihenfolge angegeben werden. Wenn beispielsweise ein Testfall vorliegt, der den AP-Server und den DB-Server verbindet, Die Ausführungsreihenfolge muss DB-Server-Start → AP-Server-Start sein.

Verwenden Sie in diesem Fall die Klasse org.junit.rules.RuleChain für Sie können die Ausführungsreihenfolge in Form von ** Verkettungsregelausführungen ** steuern. (Muster der Verantwortungskette: eine Art Entwurfsmuster)

Implementierungsbeispiel für RuleChain

Die folgenden Methoden sind in der RuleChain-Klasse implementiert.

static rulechain outerrule(testrule outerrule) Geben Sie eine Regel an, die zuerst initialisiert und anschließend beendet wird

rulechain around(testrule enclosedrule) Geben Sie eine Regel an, die später initialisiert und zuerst beendet wird

Wenn es sich um einen Brief handelt, ist er nicht schnell eingegangen, daher wird er illustriert. スクリーンショット 2020-04-24 11.11.05.png

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

    @Test
öffentlicher Leertest() 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");
    }
}

Konsolenausgabe


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

Anwendung von RuleChain durch ClassRule

Da das Starten und Stoppen des Servers ein schwerer Prozess ist, treten mit zunehmender Anzahl von Testfällen langsame Testprobleme auf. Wenn Sie beim Starten und Beenden keine spezielle Steuerung benötigen, verwenden Sie daher die Annotation ClassRule. Sie können Ressourcen sparen, indem Sie den Server für jede Testklasse starten und stoppen.

Verweise

Dieser Artikel wurde unter Bezugnahme auf die folgenden Informationen verfasst.

Recommended Posts

Was sind die Regeln in JUnit?
Was tun, wenn die Änderungen im Servlet nicht berücksichtigt werden?
Was ist die Hauptmethode in Java?
Refactoring in JUnit
Was ich in Java gelernt habe (Teil 2) Was sind Variablen?
Was sind die Vorteile von DI und Thymeleaf?
Was tun, wenn die Änderungen nicht in der JAR-Manifestdatei berücksichtigt werden?
Ist der Bruch nicht schlecht in der Programmierung? Die Geschichte.
Persönliche Zusammenfassung der in JUnit 4 häufig verwendeten Typen
Worauf ich beim ActiveModel :: Serializer-Test gestoßen bin
Was ist, wenn die Ergebnisse von Summe und Injektion (: +) unterschiedlich sind?
Der Fall, dass @Autowired in JUnit5 nicht verwendet werden konnte
Identifizieren Sie Threads im Java-Prozess, die CPU verschwenden
Was ist die Darstellung von Domänenwissen im [DDD] -Modell?
Der Zeilenumbruch des eingegebenen Textes wird in der Ansicht nicht angezeigt
Wenn die Submodul-Assets nicht im Play Framework gefunden werden
Überprüfen Sie, ob Ethereum-Transaktionen nicht im Block enthalten sind
Informationen zu Validierungsmethoden in JUnit
[Verständnis in 3 Minuten] Was ist Ruby-Vererbung? Nur die wichtigsten Punkte werden leicht verständlich erklärt!
[Schienen] Was sind starke Parameter?
Was ist die BufferedReader-Klasse?
Testen Sie private Methoden in JUnit
[Umgebungsvariablen] Schienen Was sind Umgebungsvariablen?
Welche Revolution passiert in der Programmierung
Testen Sie private Methoden in JUnit
Was sind praktisch endgültige Variablen?
config.ru Was machst du?
[JUnit] Testen Sie die ausgelöste Ausnahme
Wofür ist der Konstruktor?
Was sind Sicherheitslücken bei Massenzuweisungen?
JavaFX-Bild im Hintergrund laden
Was sind Java-Metriken? _Memo_20200818
Was ist die Initialisierungsmethode?
Was Anfänger in der Android-Entwicklung vor der Veröffentlichung der App in 2 Wochen getan haben
Was ist, wenn ich eine finally-Klausel in die Try-with-Resources-Syntax schreibe?
[Spring Boot] Verspotten Sie die Inhalte, die außerhalb des Bereichs automatisch verdrahtet werden. [JUnit 5]
Das Problem, dass XML-Attribute in Android Studio willkürlich neu angeordnet werden
Was ich bei der Migration von der Spring Boot 1.4-Serie zur 2.0-Serie getan habe
Was tun, wenn Cloud 9 im Rails-Lernprogramm voll ist?
Was ist @Override oder @SuppressWarnings ("SleepWhileInLoop") vor der Funktion? ?? ??
Was ich bei der Migration von der Spring Boot 1.5-Serie zur 2.0-Serie getan habe
Beurteilen Sie, ob die zu vergleichenden Zeichenfolgen in Java identisch sind
Was ist mit den typischen Änderungen in Apache Wicket 8 passiert?
Was tun, wenn Sie Ihr Root-Passwort unter CentOS7 vergessen haben?
Finden Sie aus den jstack-Ergebnissen heraus, was viele Threads tun