J'ai une configuration @Test sur un script qui s'exécute avec des assertions logicielles. Cependant, je rencontre un problème avec le placement de AssertAll. Je veux que toutes les URL passent avant l'assertall. Est-ce possible ou est une autre approche recommandée. Merci.
@Test
public static void checkUrl(String requestUrl, String expectedUrl){
SoftAssert softAssert = new SoftAssert ();
try {
URL obj = new URL(requestUrl);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setReadTimeout(5000);
conn.addRequestProperty("Accept-Language", "en-US,en;q=0.8");
conn.addRequestProperty("User-Agent", "Mozilla");
conn.addRequestProperty("Referer", "google.com");
System.out.println();
System.out.println("Request URL ... " + requestUrl);
boolean redirect = false;
// normally, 3xx is redirect
int status = conn.getResponseCode();
if (status != HttpURLConnection.HTTP_OK) {
if (status == HttpURLConnection.HTTP_MOVED_TEMP
|| status == HttpURLConnection.HTTP_MOVED_PERM
|| status == HttpURLConnection.HTTP_SEE_OTHER) redirect = true;
}
System.out.println("Response Code ... " + status);
if (redirect) {
// get redirect url from "location" header field
String redirectUrl = conn.getHeaderField("Location");
// get the cookie if need, for login
String cookies = conn.getHeaderField("Set-Cookie");
// open the new connnection again
conn = (HttpURLConnection) new URL(redirectUrl).openConnection();
conn.setRequestProperty("Cookie", cookies);
conn.addRequestProperty("Accept-Language", "en-US,en;q=0.8");
conn.addRequestProperty("User-Agent", "Mozilla");
conn.addRequestProperty("Referer", "google.com");
System.out.println("Redirect to URL : " + redirectUrl);
//Assert.assertEquals (redirectUrl, expectedUrl);
softAssert.assertEquals (redirectUrl, expectedUrl, "Expected URL does not match"
+ requestUrl);
} else {
//org.testng.Assert.assertTrue (redirect);
softAssert.assertTrue (redirect, "Please check the status for " + requestUrl);
System.out.println("** Please check status for " + requestUrl);
System.out.println("************************************************");
System.out.println("************************************************");
}
}
catch (Exception e) {
e.printStackTrace();
}
}
Le cas d'utilisation que vous recherchez, en quelque sorte va à l'encontre de l'objectif de SoftAssert
. SoftAssert
a été fondamentalement introduit dans TestNG, afin que vous puissiez rassembler toutes les assertions dans une méthode @Test
, mais échouer à la méthode de test uniquement à la fin (lorsque vous appelez assertAll()
).
Une méthode @Test
pilotée par les données est fondamentalement une méthode @Test
qui exécute "n" times (chaque itération est exécutée avec un ensemble de données différent). Il n’est donc pas logique pour vous d’essayer d’utiliser SoftAssert
et d’invoquer sa assertAll()
lors de la dernière itération. Parce que si vous faites cela, cela se résumera à la dernière échec de la dernière itération.
Donc, si vous envisagez de réexécuter des tests en utilisant le testng-failed.xml
, il ne contiendrait que l'index de la dernière itération (ce qui est un peu absurde, car ce n'est pas la dernière itération qui a réellement échoué).
Donc idéalement, vous ne devriez utiliser SoftAssert
que dans le cadre d'une seule itération. Cela signifie que vous instanciez un objet SoftAssert
dans une méthode @Test
, appelez un ensemble d'appels assertXXX()
et à la fin de la méthode, vous appelez assertAll()
.
Tout compte fait, si vous êtes toujours à la recherche d'un échantillon qui vous montre comment faire cela, voici un exemple.
Nous définissons d'abord une interface qui me permet de définir la taille du jeu de données fourni par le fournisseur de données en tant qu'attribut de la classe de test.
public interface IDataSet {
void setSize(int size);
}
La classe de test ressemble à celle ci-dessous
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.annotations.TestInstance;
import org.testng.asserts.SoftAssert;
import Java.util.concurrent.atomic.AtomicInteger;
public class SoftAssertDemo implements IDataSet {
private int size;
private SoftAssert assertion = new SoftAssert();
private AtomicInteger counter = new AtomicInteger(1);
@Override
public void setSize(int size) {
this.size = size;
}
@Test(dataProvider = "dp")
public void testMethod(int number) {
if ((number % 2) == 0) {
assertion.fail("Simulating a failure for " + number);
}
if (counter.getAndIncrement() == size) {
assertion.assertAll();
}
}
@DataProvider(name = "dp")
public Object[][] getData(@TestInstance Object object) {
Object[][] data = new Object[][] {{1}, {2}, {3}, {4}, {5}};
if (object instanceof IDataSet) {
((IDataSet) object).setSize(data.length);
}
return data;
}
}
Mises en garde dans cette approche:
@DataProvider
car le fournisseur de données transmet la taille de l'ensemble de données à l'instance de la classe de test. Donc, si vous avez 2 fournisseurs de données ou plus, il y a une chance que les données se poursuivent, un fournisseur de données écrasant l'autre.@Test
qui sont alimentées par les fournisseurs de données ne s'exécutent pas en parallèle.J'ai utilisé une méthode @DataProvider et @Test. La méthode @Test a pris le String [] [] du @DataProvider. Je n'ai alors pas eu besoin du pour chaque boucle. Je viens de mettre Assert All après la méthode checkUrl qui a Assert True et Assert Equals.
@Test(dataProvider = “Urls”)
public static void TestURLRedirectCheck2(String RURL, String EURL){
checkUrl(RURL, EURL);
softAssert.assertAll ();
}