Pular para o conteúdo

Folha de Dicas Abrangente do TestNG

Folha de Dicas Abrangente do TestNG

Instalação

Plataforma/FerramentaMétodo de Instalação
MavenAdd to pom.xml:
<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>7.8.0</version>
  <scope>test</scope>
</dependency>
GradleAdd to build.gradle:
testImplementation 'org.testng:testng:7.8.0'
Eclipse IDEAjuda → Eclipse Marketplace → Pesquisar “TestNG” → Instalar
IntelliJ IDEAAgrupado por padrão (ou File → Settings → Plugins → Marketplace → “TestNG”)
VS Codecode --install-extension vscjava.vscode-java-pack
code --install-extension testng.testng
Manual (Linux/macOS)wget https://repo1.maven.org/maven2/org/testng/testng/7.8.0/testng-7.8.0.jar
export CLASSPATH=$CLASSPATH:/path/to/testng-7.8.0.jar
Manual (Windows)Download JAR from Maven Central
set CLASSPATH=%CLASSPATH%;C:\path\to\testng-7.8.0.jar

Anotações Principais

AnotaçãoDescrição
@TestMarca um método como um método de teste
@Test(priority = 1)Define a ordem de execução (números menores são executados primeiro)
@Test(description = "...")Adiciona texto descritivo para teste de relatório
@Test(timeOut = 5000)Falha no teste se a execução exceder o tempo limite (milissegundos)
@Test(expectedExceptions = Exception.class)Espera que uma exceção específica seja lançada
@Test(enabled = false)Desativa/pula o teste
@Test(groups = {"smoke", "regression"})Atribui teste a um ou mais grupos
@Test(dependsOnMethods = {"testMethod"})Executa após o método(s) especificado(s) ser(em) concluído(s)
@Test(dependsOnGroups = {"smoke"})Executa após todos os testes no(s) grupo(s) especificado(s)
@Test(alwaysRun = true)Executa teste mesmo se dependências falharem
@Test(invocationCount = 3)Executa teste múltiplas vezes
@Test(threadPoolSize = 5)Executa múltiplas invocações em threads paralelos
@BeforeMethodExecutes before each @Test method
@AfterMethodExecutes after each @Test method
@BeforeClassExecuta uma vez antes de qualquer método de teste na classe
@AfterClassExecuta uma vez após todos os métodos de teste na classe
@BeforeTestExecutes before any test method in <test> tag
@AfterTestExecutes after all test methods in <test> tag
@BeforeSuiteExecuta uma vez antes de todos os testes na suíte
@AfterSuiteExecuta uma vez após todos os testes na suíte
@BeforeGroupsExecuta antes do primeiro método de teste do(s) grupo(s) especificado(s)
@AfterGroupsExecuta após o último método de teste do(s) grupo(s) especificado(s)
@DataProviderFornece dados para testar métodos de parametrização
@ParametersInjects parameters from testng.xml into test methods
@FactoryCria instâncias de teste dinamicamente
@ListenersAnexa ouvintes personalizados à classe de teste

Execução via Linha de Comando

ComandoDescrição
java -cp "classes:lib/*" org.testng.TestNG testng.xmlExecutar testes usando arquivo de suite XML
java -cp "classes:lib/*" org.testng.TestNG -testclass com.example.MyTestExecutar classe de teste específica
java -cp "classes:lib/*" org.testng.TestNG -testclass Test1,Test2Execute várias classes de teste (separadas por vírgula)
java -cp "classes:lib/*" org.testng.TestNG -groups smoke testng.xmlExecutar testes de grupo(s) específico(s)
java -cp "classes:lib/*" org.testng.TestNG -excludegroups slow testng.xmlExcluir grupo(s) específico(s) da execução
java -cp "classes:lib/*" org.testng.TestNG -d test-output testng.xmlEspecificar diretório de saída para relatórios
java -cp "classes:lib/*" org.testng.TestNG -parallel methods -threadcount 5Execute testes em paralelo com contagem de threads
java -cp "classes:lib/*" org.testng.TestNG -verbose 10 testng.xmlDefinir nível de verbosidade (0-10, maior = mais detalhes)
java -cp "classes:lib/*" org.testng.TestNG -methods MyTest.test1,MyTest.test2Executar métodos de teste específicos
java -cp "classes:lib/*" org.testng.TestNG -suitename "MySuite" -testname "MyTest"Substituir nomes de suíte e teste
java -cp "classes:lib/*" org.testng.TestNG -reporter org.testng.reporters.EmailableReporterUse um reporter específico
java -cp "classes:lib/*" org.testng.TestNG -listener com.example.MyListenerAdicionar listener personalizado

Comandos Maven

ComandoDescrição
mvn testExecutar todos os testes
mvn test -Dtest=MyTestClassExecutar classe de teste específica
mvn test -Dtest=MyTestClass#testMethodExecutar método de teste específico
mvn test -Dtest=MyTestClass#test*Executar métodos de teste correspondentes ao padrão
mvn test -DsuiteXmlFile=smoke-tests.xmlExecutar arquivo XML de suite específico
mvn test -Dgroups=smoke,regressionExecutar grupos de testes específicos
mvn test -DexcludedGroups=slowExcluir grupos de teste específicos
mvn test -Denvironment=staging -Dbrowser=chromePassar propriedades do sistema para testes
mvn test -DskipTestsIgnorar execução de teste
mvn test -Dmaven.test.failure.ignore=trueContinue build mesmo se os testes falharem
mvn test -Dparallel=methods -DthreadCount=4Executar testes em paralelo
mvn clean testLimpar builds anteriores e executar testes
mvn test -XExecutar testes com saída de depuração
mvn surefire-report:reportGerar relatório de teste HTML

Comandos Gradle

ComandoDescrição
gradle testExecutar todos os testes
gradle test --tests MyTestClassExecutar classe de teste específica
gradle test --tests MyTestClass.testMethodExecutar método de teste específico
gradle test --tests *IntegrationTestExecutar testes correspondentes ao padrão
gradle test --tests MyTestClass --tests OtherTestExecutar múltiplas classes de teste
gradle test -Denvironment=stagingPassar propriedades do sistema
gradle clean testLimpar e executar testes
gradle test --infoExecutar com registro detalhado
gradle test --debugExecutar com registro de log em nível de depuração
gradle test --rerun-tasksForçar execução novamente mesmo se estiver atualizado
gradle test --continueContinuar execução após falhas de teste
gradle test --fail-fastParar execução no primeiro erro de teste

Métodos de Asserção

MétodoDescrição
Assert.assertEquals(actual, expected)Verificar se dois valores são iguais
Assert.assertEquals(actual, expected, "message")Afirmar com mensagem de falha personalizada
Assert.assertNotEquals(actual, expected)Verificar se dois valores não são iguais
Assert.assertTrue(condition)Verificar se a condição é verdadeira
Assert.assertFalse(condition)Verificar condição é falso
Assert.assertNull(object)Verificar se objeto é nulo
Assert.assertNotNull(object)Verifique se o objeto não é nulo
Assert.assertSame(actual, expected)Verificar referência do mesmo objeto
Assert.assertNotSame(actual, expected)Verificar diferentes referências de objetos
Assert.fail("message")Falhar explicitamente um teste
Assert.assertThrows(Exception.class, () -> {...})Verificar se a exceção é lançada
Assert.expectThrows(Exception.class, () -> {...})Igual a assertThrows (alias)

Provedores de Dados

PadrãoDescrição
@DataProvider(name = "testData")Definir um método de provedor de dados
@Test(dataProvider = "testData")Usar provedor de dados no teste
@DataProvider(parallel = true)Executar iterações de provedor de dados em paralelo
Object[][] dataProvider()Retornar array 2D de dados de teste
Iterator<Object[]> dataProvider()Retornar iterador para grandes conjuntos de dados
@DataProvider(indices = {0, 2, 4})Executar apenas índices de conjunto de dados específicos

Exemplo de Provedor de Dados

@DataProvider(name = "loginData")
public Object[][] getLoginData() {
    return new Object[][] {
        {"user1", "pass1", true},
        {"user2", "pass2", false},
        {"user3", "pass3", true}
    };
}

@Test(dataProvider = "loginData")
public void testLogin(String username, String password, boolean expected) {
    boolean result = login(username, password);
    Assert.assertEquals(result, expected);
}

Configuração XML do TestNG

Configuração Básica de Suite

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Test Suite" parallel="methods" thread-count="5" verbose="1">
    
    <!-- Suite-level parameters -->
    <parameter name="browser" value="chrome"/>
    <parameter name="environment" value="staging"/>
    
    <!-- Define test groups -->
    <test name="Smoke Tests">
        <groups>
            <run>
                <include name="smoke"/>
                <exclude name="slow"/>
            </run>
        </groups>
        
        <!-- Specify test classes -->
        <classes>
            <class name="com.example.LoginTest"/>
            <class name="com.example.SearchTest">
                <!-- Include specific methods -->
                <methods>
                    <include name="testBasicSearch"/>
                    <include name="testAdvancedSearch"/>
                </methods>
            </class>
        </classes>
    </test>
    
    <!-- Another test configuration -->
    <test name="Regression Tests">
        <packages>
            <package name="com.example.regression.*"/>
        </packages>
    </test>
    
    <!-- Listeners -->
    <listeners>
        <listener class-name="com.example.CustomListener"/>
    </listeners>
</suite>

Configuração de Execução Paralela

<!-- Parallel at suite level -->
<suite name="Parallel Suite" parallel="tests" thread-count="3">
    <test name="Test1">...</test>
    <test name="Test2">...</test>
</suite>

<!-- Parallel options: methods, tests, classes, instances -->

Configuração do Plugin Maven Surefire

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0</version>
            <configuration>
                <!-- Specify suite files -->
                <suiteXmlFiles>
                    <suiteXmlFile>testng.xml</suiteXmlFile>
                    <suiteXmlFile>smoke-tests.xml</suiteXmlFile>
                </suiteXmlFiles>
                
                <!-- Run specific groups -->
                <groups>smoke,regression</groups>
                <excludedGroups>slow,manual</excludedGroups>
                
                <!-- Parallel execution -->
                <parallel>methods</parallel>
                <threadCount>5</threadCount>
                
                <!-- System properties -->
                <systemPropertyVariables>
                    <browser>chrome</browser>
                    <environment>staging</environment>
                </systemPropertyVariables>
                
                <!-- Continue on failures -->
                <testFailureIgnore>false</testFailureIgnore>
            </configuration>
        </plugin>
    </plugins>
</build>

Configuração de Teste Gradle

test {
    useTestNG() {
        // Suite files
        suites 'src/test/resources/testng.xml'
        
        // Include/exclude groups
        includeGroups 'smoke', 'regression'
        excludeGroups 'slow'
        
        // Parallel execution
        parallel = 'methods'
        threadCount = 5
        
        // Preserve order
        preserveOrder = true
        
        // Group by instances
        groupByInstances = true
    }
    
    // System properties
    systemProperty 'browser', 'chrome'
    systemProperty 'environment', 'staging'
    
    // Test output
    testLogging {
        events "passed", "skipped", "failed"
        exceptionFormat "full"
    }
}

Casos de Uso Comuns

Caso de Uso 1: Classe de Teste Básica com Setup e Teardown

import org.testng.annotations.*;
import org.testng.Assert;

public class UserManagementTest {
    
    private DatabaseConnection db;
    private UserService userService;
    
    @BeforeClass
    public void setupClass() {
        // Initialize database connection once for all tests
        db = new DatabaseConnection("jdbc:mysql://localhost:3306/testdb");
        db.connect();
    }
    
    @BeforeMethod
    public void setupMethod() {
        // Create fresh service instance before each test
        userService = new UserService(db);
    }
    
    @Test(priority = 1, groups = {"smoke"})
    public void testCreateUser() {
        User user = userService.createUser("john@example.com", "John Doe");
        Assert.assertNotNull(user.getId());
        Assert.assertEquals(user.getEmail(), "john@example.com");
    }
    
    @Test(priority = 2, dependsOnMethods = {"testCreateUser"})
    public void testFindUser() {
        User user = userService.findByEmail("john@example.com");
        Assert.assertNotNull(user);
        Assert.assertEquals(user.getName(), "John Doe");
    }
    
    @AfterMethod
    public void cleanupMethod() {
        // Clean up test data after each test
        userService.deleteAllUsers();
    }
    
    @AfterClass
    public void cleanupClass() {
        // Close database connection after all tests
        db.disconnect();
    }
}

Caso de Uso 2: Teste Orientado a Dados com DataProvider

import org.testng.annotations.*;
import org.testng.Assert;

public class LoginTest {
    
    private LoginPage loginPage;
    
    @BeforeMethod
    public void setup() {
        loginPage = new LoginPage();
        loginPage.open();
    }
    
    @DataProvider(name = "loginCredentials")
    public Object[][] getLoginData() {
        return new Object[][] {
            {"valid@user.com", "ValidPass123", true, "Dashboard"},
            {"invalid@user.com", "WrongPass", false, "Invalid credentials"},
            {"", "password", false, "Email is required"},
            {"user@test.com", "", false, "Password is required"},
            {"admin@test.com", "AdminPass!", true, "Admin Panel"}
        };
    }
    
    @Test(dataProvider = "loginCredentials")
    public void testLogin(String email, String password, 
                         boolean shouldSucceed, String expectedMessage) {
        loginPage.enterEmail(email);
        loginPage.enterPassword(password);
        loginPage.clickLogin();
        
        if (shouldSucceed) {
            Assert.assertTrue(loginPage.isLoggedIn());
            Assert.assertEquals(loginPage.getPageTitle(), expectedMessage);
        } else {
            Assert.assertTrue(loginPage.hasError());
            Assert.assertTrue(loginPage.getErrorMessage().contains(expectedMessage));
        }
    }
    
    @AfterMethod
    public void teardown() {
        loginPage.close();
    }
}

Caso de Uso 3: Execução de Testes Paralelos com Grupos

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Parallel Test Suite" parallel="tests" thread-count="3">
    
    <test name="Chrome Tests" parallel="methods" thread-count="2">
        <parameter name="browser" value="chrome"/>
        <groups>
            <run>
                <include name="smoke"/>
            </run>
        </groups>
        <classes>
            <class name="com.example.tests.HomePageTest"/>
            <class name="com.example.tests.SearchTest"/>
        </classes>
    </test>
    
    <test name="Firefox Tests" parallel="methods" thread-count="2">
        <parameter name="browser" value="firefox"/>
        <groups>
            <run>
                <include name="smoke"/>
            </run>
        </groups>
        <classes>
            <class name="com.example.tests.HomePageTest"/>
            <class name="com.example.tests.SearchTest"/>
        </classes>
    </test>
    
    <test name="API Tests" parallel="classes" thread-count="3">
        <groups>
            <run>
                <include name="api"/>
            </run>
        </groups>
        <packages>
            <package name="com.example.api.*"/>
        </packages>
    </test>
</suite>
// Test class using parameters
public class CrossBrowserTest {
    
    private WebDriver driver;
    
    @Parameters({"browser"})
    @BeforeMethod
    public void setup(String browser) {
        if (browser.equalsIgnoreCase("chrome")) {
            driver = new ChromeDriver();
        } else if (browser.equalsIgnoreCase("firefox")) {
            driver = new FirefoxDriver();
        }
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
    }
    
    @Test(groups = {"smoke"})
    public void testHomePage() {
        driver.get("https://example.com");
        Assert.assertEquals(driver.getTitle(), "Example Domain");
    }
    
    @AfterMethod
    public void teardown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

Caso de Uso 4: Teste de API com Lógica de Retry

import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

// Retry analyzer for flaky tests
public class RetryAnalyzer implements IRetryAnalyzer {
    private int retryCount = 0;
    private static final int MAX_RETRY = 3;
    
    @Override
    public boolean retry(ITestResult result) {
        if (retryCount < MAX_RETRY) {
            retryCount++;
            return true;
        }
        return false;
    }
}

// API Test class
public class APITest {
    
    private RestClient client;
    
    @BeforeClass
    public void setup() {
        client = new RestClient("https://api.example.com");
    }
    
    @Test(groups = {"api"}, retryAnalyzer = RetryAnalyzer.class)
    public void testGetUser() {
        Response response = client.get("/users/1");
        Assert.assertEquals(response.getStatusCode(), 200);
        Assert.assertNotNull(response.jsonPath().getString("name"));
    }
    
    @Test(groups = {"api"}, dependsOnMethods = {"testGetUser"})
    public void testCreateUser() {
        String payload = "{\"name\":\"John\",\"email\":\"john@test.com\"}";
        Response response = client.post("/users", payload);
        Assert.assertEquals(response.getStatusCode(), 201);
    }
    
    @Test(groups = {"api"}, timeOut = 5000)
    public void testPerformance() {
        long startTime = System.currentTimeMillis();
        Response response = client.get("/users");
        long endTime = System.currentTimeMillis();
        
        Assert.assertEquals(response.getStatusCode(), 200);
        Assert.assertTrue((endTime - startTime) < 3000, 
            "API response time exceeded 3 seconds");
    }
}

Caso de Uso 5: Listeners Personalizados e Relatórios

import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.ITestContext;

public class CustomTestListener implements ITestListener {
    
    @Override
    public void onTestStart(ITestResult result) {
        System.out.println("Starting test: " + result.getName());
    }
    
    @Override
    public void onTestSuccess(ITestResult result) {
        System.out.println("Test passed: " + result.getName());
    }
    
    @Override
    public void onTestFailure(ITestResult result) {
        System.out.println("Test failed: " + result.getName());
        // Take screenshot, log error, etc.
        captureScreenshot(result.getName());
    }
    
    @Override
    public void onTestSkipped(ITestResult result) {
        System.out.println("Test skipped: " + result.getName());
    }
    
    @Override
    public void onFinish(ITestContext context) {
        System.out.println("Total tests run: " + context.getAllTestMethods().length);
        System.out.println("Passed: " + context.getPassedTests().size());
        System.out.println("Failed: " + context.getFailedTests().size());
        System.out.println("Skipped: " + context.getSkippedTests().size());
    }
    
    private void captureScreenshot(String testName) {
        // Screenshot logic here
    }
}

// Using the listener
@Listeners(CustomTestListener.class)
public class MyTest {
    
    @Test
    public void testExample() {
        Assert.assertTrue(true);
    }
}

Melhores Práticas

  • Use nomes de teste significativos: Nomeie os testes de forma clara para descrever o que eles verificam (por exemplo, testUserCanLoginWithValidCredentialsem vez de

Note: For items 1-20 where no specific text was provided, I’ve translated the headings and maintained the structure. If you have specific text for those items, please provide them and I’ll translate accordingly.test1- Aproveite grupos de forma eficaz: Organize testes em grupos lógicos (smoke, regression, api, ui) para executar subconjuntos de testes com base no contexto e economizar tempo de execução

  • Implemente configuração e desmontagem adequadas: Use @BeforeMethod/@AfterMethodpara configuração de nível de teste e @BeforeClass/@AfterClasspara operações caras como conexões de banco de dados

  • Torne os testes independentes: Cada teste deve ser autossuficiente e não depender da ordem de execução ou estado compartilhado. Use dependsOnMethodscom parcimônia e apenas quando existir dependência lógica

  • Use DataProviders para dados de teste: Separe os dados de teste de

Would you like me to complete the remaining placeholders or provide the full context for translation?