
image source: pixabay
지난 시간에 잠시 언급했던 TestNG annotation 중 @Test annotation의 속성을 좀 더 알아본다. @Test annotation은 테스트하려는 하나의 케이스를 표현한다. 이를테면 로그인, 글쓰기 등을 하나의 케이스로 볼 수 있겠다. 이런 케이스 메소드 위에 @Test를 넣어 케이스를 쉽게 관리할 수 있고 속성을 추가하여 부가적인 기능도 추가할 수 있다.
아래 예제를 한번 보자.
- 총 세 개의 케이스를 지정한다.
enabled속성으로 해당 케이스를 실행할지 안 할지 설정한다. 디폴트 값은 true이고 false일 경우 이 케이스를 건너뛴다.@Test앞에 주석(//)만 추가하면 동일 기능인데 무슨 차이가 있는지, 왜 사용해야 하는지는 잘 모르겠다.description은 말 그대로 이 케이스의 설명이고, 상세하게 기입할수록 좋을 것 같다.timeOut는 이 케이스가 실행되는 기대 시간이다. 시간을 초과하면 Exception이 발생하고 리포트에 Fail로 기록된다. UI 자동화에서는 큰 효과가 있을지 의문이지만, 속도를 중요시하는 API 테스트일 경우 상당한 효과가 있을 것으로 보인다.
@Test(enabled = false, description = "글 목록을 불러온다.")
public void CASE_01_GetPosts() {
.... Some Action ...
}
@Test(timeOut = 60000, description = "로그인 한다.")
public void CASE_02_Login() {
.... Some Action ...
}
@Test(description = "스팀잇에 글 쓰기 한다. ")
public void CASE_03_Write() {
.... Some Action ...
}
위 예제에서 메소드 명에 번호가 추가되어 있는데 이는 TestNG가 테스트를 수행할 때 순서를 정하기 위함이다. TestNG는 메소드 name ascending 순으로 테스트를 수행한다. 하지만 메소드에 꼭 번호를 매겨야 하는 건 아니다. 이 또한 속성으로 대신할 수 있는데 priority 속성으로 순서를 정할 수 있다.
@Test(priority = 3, description = "스팀잇에 글 쓰기 한다. ")
public void Write() {
.... Some Action ...
}
이 외에도 dependsOnMethods, groups, dataProvider,dataProviderClass 등 다양한 속성이 존재하는데 나중에 필요할 때 차차 다루도록 한다.
package com.steem.webatuo;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import io.github.bonigarcia.wdm.WebDriverManager;
public class Steemit {
WebDriver driver;
@BeforeClass
public void SetUp() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.get("STEEMIT URL");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
}
@Test(enabled = false, description = "글 목록을 불러온다.")
public void CASE_01_GetPosts() {
List<WebElement> list = driver.findElements(By.xpath("//div[@id='posts_list']/ul/li"));
assertTrue(!list.isEmpty(), "글 목록이 있는지 확인");
for (WebElement post : list) {
String title = post.findElement(By.xpath("descendant::h2/a")).getText();
String author = post.findElement(By.xpath("descendant::span[@class='user__name']")).getText();
System.out.println(author + "님의 글: " + title);
}
}
@Test(timeOut = 60000, description = "로그인 한다.")
public void CASE_02_Login() throws InterruptedException {
// Click the login button
driver.findElement(By.linkText("로그인")).click();
// type id
driver.findElement(By.name("username")).sendKeys("june0620");
// type pw and submit
WebElement pw = driver.findElement(By.name("password"));
assertNotNull(pw, "비밀번호 태그가 노출되는지 확인");
pw.sendKeys(Password.getPw());
pw.submit();
Thread.sleep(5000);
}
@Test(description = "스팀잇에 글 쓰기 한다. ")
public void CASE_03_Write() throws InterruptedException {
// Click the write Button
List<WebElement> writeBtns = driver.findElements(By.xpath("//a[@href='/submit.html']"));
assertEquals(writeBtns.size(), 1, "글쓰기 버튼이 노출되는지 확인");
for (WebElement writeBtn : writeBtns) {
if (writeBtn.isDisplayed()) {
writeBtn.click();
Thread.sleep(2000);
// type Text and Keys
WebElement editor = driver.findElement(By.xpath("//textarea[@name='body']"));
String keys = Keys.chord(Keys.LEFT_SHIFT, Keys.ENTER);
editor.sendKeys("hello!! world", keys, "hello!!! STEEMIT", Keys.ENTER, "안녕, 스팀잇", Keys.ENTER, "你好!似提姆");
break;
}
}
Thread.sleep(5000);
}
@AfterClass
public void tearDownClass() {
driver.quit();
}
}
.
.
.
.
[Cookie 😅]
Seleniun java lib version: 3.141.59
java version: 13.0.1
@tipu curate
!shop
来自于 [WhereIn Android] (http://www.wherein.io)
Upvoted 👌 (Mana: 5/15 - need recharge?)
晚上好啊😀😎
我在这呢🤭
Posted using Partiko Android
晚上好萍萍 😄
你好鸭,june0620!
@yanhan给您叫了一份外卖!
巧克力蛋糕

吃饱了吗?跟我猜拳吧! 石头,剪刀,布~
如果您对我的服务满意,请不要吝啬您的点赞~