Testng: unterstützende Parameter auf Methodenebene?

Erstellt am 12. Okt. 2015  ·  12Kommentare  ·  Quelle: cbeust/testng

Ist es möglich, spezielle Parameter auf Methodenebene zu unterstützen?
Zum Beispiel,

<test name="Regression1">
<groups>
    <run>
      <exclude name="brokenTests"  />
      <include name="checkinTests"  />
    </run>
  </groups>

  <classes>
    <class name="test.IndividualMethodsTest">
      <methods>
        <include name="testMethod" param1="121" param2="1212"  />
      </methods>
    </class>
  </classes>
</test>

Ich versuche, dies zu erreichen, indem ich den Testng-Code ändere - ich würde mich über jede Anleitung/Start dafür freuen.

Hilfreichster Kommentar

Tatsächlich existieren Parameter auf Methodenebene. Hier ist ein Beispiel:

<suite name="my-suite" verbose="1">
    <test name="my-test">
        <classes>
            <class name="testng.ex1.TestParams">
                <methods>
                    <include name="m1">
                        <parameter name="key1"  value="val1"/>
                        <parameter name="key2"  value="val2"/>
                    </include>
                    <include name="m2">
                        <parameter name="key1"  value="valA"/>
                        <parameter name="key2"  value="valB"/>
                    </include>
                </methods>
            </class>
        </classes>
    </test>
</suite>
package testng.ex1;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class TestParams {

    <strong i="8">@Test</strong>
    @Parameters({ "key1", "key2" })
    public void m1(String key1, String key2) throws Exception {
        System.out.println(key1 + ", " + key2);
    }

    <strong i="9">@Test</strong>
    @Parameters({ "key1", "key2" })
    public void m2(String key1, String key2) throws Exception {
        System.out.println(key1 + ", " + key2);
    }
}

Alle 12 Kommentare

Nein, Sie sollten dafür ein @DataProvider verwenden.

@cbeust , die Herausforderung bei @DataProvider ist, dass es nicht aus testng.xml definiert werden kann? Der Grund für die Übergabe dieses Parameters ist, dass die Daten für die Methode aus einer Datenbank stammen und dieser Parameter der Primärschlüssel ist. Ich möchte diesen Schlüssel verwenden, Daten abrufen und mithilfe von Reflektion zur Laufzeit ein Datenobjekt für die Methode erstellen. Kurz gesagt, selbst wenn ich einen DataProvider verwende, muss ich ihm zur Laufzeit einen Wert übergeben, um anzugeben, welche Zeilen aus der Datenbank ausgewählt werden sollen. Bitte beachten Sie, dass dies für ein Szenario mit programmgesteuerter Verwendung von testng gilt.

Sie können eine begrenzte Anzahl von Parametern in Ihrem testng.xml definieren:

http://testng.org/doc/documentation-main.html#parameters-testng-xml

Cedric

Am Montag, den 12. Oktober 2015 um 21:03 Uhr schrieb JayVem [email protected] :

@cbeust https://github.com/cbeust , die Herausforderung bei @DataProvider ist
dass es nicht aus testng.xml definiert werden kann? Der Grund für die Weitergabe dieser
Parameter, ist, dass die Daten für die Methode aus einer Datenbank stammen und diese
Parameter ist der Primärschlüssel. Ich möchte diesen Schlüssel verwenden, Daten abrufen, eine erstellen
Datenobjekt für die Methode zur Laufzeit mit Reflektion. Also kurz gesagt sogar
Wenn ich einen DataProvider verwende, muss ich ihm zur Laufzeit einen Wert übergeben, to
Geben Sie an, welche Zeilen aus der Datenbank ausgewählt werden sollen. Bitte beachten Sie dies
ist für ein Szenario mit programmgesteuerter Verwendung von testng.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/cbeust/testng/issues/823#issuecomment -147592710.

@cbeust Sind diese Parameter nicht auf Suite-Ebene? Was wäre, wenn ich einen komplexen Datentyp auf Methodenebene erstellen wollte. Betrachten Sie zum Beispiel diesen Code ...

public class EmployeeBenefitsCalculator {

    <strong i="7">@Test</strong>
    public void calculateBenefits(Employee employee) {
        //do something with employee here.
    }
}

Der Employee-Parameter, der an die computeBenefits-Methode gesendet wird, muss aus der Datenbank erstellt werden. Wie würde ich das erreichen? Ich möchte einen Primärschlüssel übergeben und innerhalb der computeBenefits-Methode möchte ich diesen Primärschlüssel lesen, Daten aus der Datenbank abrufen und ein Mitarbeiterobjekt für diesen Testlauf erstellen. Ich weiß, es klingt kompliziert. Ich glaube, das ist es, was ich suche -

public class EmployeeBenefitsCalculator {

    <strong i="11">@Test</strong>
    public void calculateBenefits(Employee employee) {
        employee = DataStore.fetch("id_from_testng_xml");
    }
}

Wie stelle ich einem Datenanbieter Parameter für einen Test zur Laufzeit bereit? Wie einfach ist es, dieses Verhalten durch Ändern der Testng-Quelle zu ändern?

Sie können Datenanbieter + Parameter mischen. Ihr Datenanbieter nimmt den Primärschlüssel aus dem Parameter und erstellt Ihr Employee-Objekt und übergibt alle anderen Attribute. Dann verwendet Ihre Testmethode den Datenanbieter und seine Attribute.
Leicht! ;)

@juherr Könnten Sie mir ein Beispiel geben, wie ich mehrere Parameter auf Methodenebene haben kann, die jeweils an einen Datenanbieter gehen?

@juherr Um meine Frage zu vereinfachen, erzeuge ich programmgesteuert eine testng.xml. Nehmen wir nun an, ich habe eine Methode modifyEmployee(Employee employee). Ich muss eine XML so erstellen, dass diese Methode 4 Mal aufgerufen wird, aber jedes Mal mit einem anderen Mitarbeiter. Ich würde den Primärschlüssel jedes dieser Mitarbeiter zum Zeitpunkt der Erstellung von testng.xml kennen. Also, was ist der beste Weg, um das zu erreichen, was ich versuche zu tun?

Ich habe angenommen, dass @DataProvider mit @Parameters arbeiten kann, aber ich bin mir nicht sicher (ich sollte es eines Tages testen).
Übrigens, wenn ich verstehe, was Sie wollen, können Sie einfach Parameter auf Testebene ausprobieren (Parameter auf Methodenebene existieren nicht):

<suite>
<test name="Regression1">
<parameter name="param1" value="121" />
<parameter name="param2" value="1212" />
<groups>
    <run>
      <exclude name="brokenTests"  />
      <include name="checkinTests"  />
    </run>
  </groups>

  <classes>
    <class name="test.IndividualMethodsTest">
      <methods>
        <include name="testMethod"  />
      </methods>
    </class>
  </classes>
</test>

<test name="Regression2">
<parameter name="param1" value="454" />
<parameter name="param2" value="4545" />
<groups>
    <run>
      <exclude name="brokenTests"  />
      <include name="checkinTests"  />
    </run>
  </groups>

  <classes>
    <class name="test.IndividualMethodsTest">
      <methods>
        <include name="testMethod"  />
      </methods>
    </class>
  </classes>
</test>
<suite>

Sie sollten Ihre Frage auf Staskoverflow oder die Mailingliste stellen, wenn Sie weitere Ideen wünschen ;)

Tatsächlich existieren Parameter auf Methodenebene. Hier ist ein Beispiel:

<suite name="my-suite" verbose="1">
    <test name="my-test">
        <classes>
            <class name="testng.ex1.TestParams">
                <methods>
                    <include name="m1">
                        <parameter name="key1"  value="val1"/>
                        <parameter name="key2"  value="val2"/>
                    </include>
                    <include name="m2">
                        <parameter name="key1"  value="valA"/>
                        <parameter name="key2"  value="valB"/>
                    </include>
                </methods>
            </class>
        </classes>
    </test>
</suite>
package testng.ex1;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class TestParams {

    <strong i="8">@Test</strong>
    @Parameters({ "key1", "key2" })
    public void m1(String key1, String key2) throws Exception {
        System.out.println(key1 + ", " + key2);
    }

    <strong i="9">@Test</strong>
    @Parameters({ "key1", "key2" })
    public void m2(String key1, String key2) throws Exception {
        System.out.println(key1 + ", " + key2);
    }
}

:+1: Gut zu wissen! Ich habe es noch nie zuvor gesehen.

@JayVem Ich schließe das Problem, da es bereits existiert.

Ein anderer Ansatz besteht darin, einen Datenanbieter zu verwenden, der die Schlüssel aus testng.xml abruft. Siehe Beispiel:

<suite name="my-suite" verbose="1">
    <test name="my-test">
        <classes>
            <parameter name="keys" value="key1,key2,key3,key4" />
            <class name="testng.ex2.TestParams" />
        </classes>
    </test>
</suite>
package testng.ex2;

import java.util.Arrays;
import java.util.List;

import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class TestParams {

    @Test(dataProvider = "dp")
    public void m1(Employee e) throws Exception {
        System.out.println("name: " + e.getName() + ", age: " + e.getAge());
    }

    @DataProvider(name = "dp")
    @Parameters("keys")
    public Object[][] createData(ITestContext ctx) {
        String keysString = ctx.getCurrentXmlTest().getLocalParameters().get("keys");
        List<String> keys = Arrays.asList(keysString.split(","));

        Object[][] result = new Object[keys.size()][1];
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            result[i] = new Object[] { new Employee(key) };
        }
        return result;
    }
}

package testng.ex2;

public class Employee {

    private final String name;
    private final int age;

    public Employee(String key) {
        // use 'key' to lookup employee in database
        name = key + "_name"; // dummy value
        age = 41; // dummy value
    }

    String getName() {
        return name;
    }

    int getAge() {
        return age;
    }
}

Danke @drapostolos , ich denke, Datenanbieter mit Testkontext klingt so, als würde es reichen. Ich werde das ausprobieren. Vielen Dank für die schnelle Antwort!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen