Post

데브코스 TIL - 셀레니움 IDE와 종단간테스트

셀레니움과 종단간테스트

✅시나리오

노트 목록 조회, 노트 선택하여 제목과 내용 확인

  • 로그인 상태에서 행할 테스트가 많으므로 로그인/로그아웃 기능은 코드 공용화
  • 사용자 상호작용이 벌어지는 HTML 요소의 선택을 명확히
  • Assertion을 삽입하여 올바른 동작을 확인/검증

실습

1. 로그인/로그아웃 테스트 라이브러리화

로그인/로그아웃은 매 테스트에서 처음과 끝에 행할 동작이기 때문에 selenium IDE를 이용하여 라이브러리화 시킴

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def test_loginlogout(self);
  self.driver.get("http://localhost:30030/")
  self.driver.set_window_size(1078, 1020)
  self.login()
  self.driver.impicitly_wait(10)
  self.logout()

def login(self):
  self.driver.find_element(By.LINK_TEXT, "무료로 시작하기").click()
  self.driver.find_element(By.ID, "emailInput").click()
  self.driver.find_element(By.ID, "emailInput").send_keys("test@example.com")
  self.driver.find_element(By.ID, "passwordInput").click()
  self.driver.find_element(By.ID, "passwordInput").send_keys("1234")
  self.driver.find_element(By.CSS_SELECTOR, ".sc-fsYfdN").click()
  
def logout(self):
  self.driver.find_element(By.CSS_SELECTOR, "#logout-button > span").click()

2. 셀레니움 IDE를 사용하여 노트 목록 조회를 위한 테스트케이스 만들기

노트 목록은 로그인이 되어있어야 하는 상태기 때문에, 로그인이 된 상태로 준비

테스트 내용

  • 로그인한 사용자가 올바르게 표시되었는가
  • 사용자가 가지고 있는 노트 (2개)가 올바르게 나오는가
  • 오래된 노트를 클릭하면 우측에 제목과 내용이 올바르게 나오는가

저장하고 다음과 같이 파일을 수정

Why?

Selenium IDE가 개발자의 의도를 알아내거나 짐작하기 어렵기 때문에 HTML 요소 선택 방식을 의도한 바에 따라 수정해야 함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# Generated by Selenium IDE
import pytest
import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

BASE URL = "http://localhost:30030" 

class TestNotesView():
  def setup_method(self, method):
    self.driver = webdriver.Chrome()
    self.vars = {}
    self.login()

  
  def teardown_method(self, method):
    self.logout()
    self.driver.quit()
  

  def test_notesview(self):
    time.sleep(1)
    self.driver.get(BASE URL + "/notes")
    self.driver.set_window_size(1078, 1020)
    self.driver.impicitly_wait(10)

    # 로그인한 사용자의 ID 확인
    assert self.driver.find_element(
      By.ID, "current-user"
    ).text == "test@example.con"

    # 노트 목록의 올바른 순서와 내용 확인
    notes_list = self.driver.find_element(By.ID, "note-list")
    assert notes_list.find_element(
      By.CSS_SELECTOR, "li:nth-child(1) span"
    ).text == "Test (2)"
    assert notes_list.find_element(
      By.CSS_SELECTOR, "li:nth-child(2) span"
    ).text == "Test (1)"

    # 목록의 맨 아래 노트 제목 클릭
    notes_list.find_element(By.XPATH, "ul[@id=\'note-list\']/li[last()]/a/span").click()
    self.driver.impicitly_wait(2)
    # 선택된 노트 제목 확인
    assert self.driver.find_element(
      By.CSS_SELECTOR, "article header textarea"
    ).text == "Test (1)"
    # 선택된 노트 내용 확인
    assert self.driver.find_element(
      By.CSS_SELECTOR, "article div div div"
    ).get_attribute('innerHTML') == "<p>This note is for testing.</p>" \
      + "<p>Note number: 1</p>"

  def login(self):
    self.driver.get(BASE URL + "/")
    self.driver.impicitly_wait(10)
    self.driver.find_element(By.LINK_TEXT, "무료로 시작하기").click()
    self.driver.find_element(By.ID, "emailInput").click()
    self.driver.find_element(By.ID, "emailInput").send_keys("test@example.com")
    self.driver.find_element(By.ID, "passwordInput").click()
    self.driver.find_element(By.ID, "passwordInput").send_keys("1234")
    self.driver.find_element(By.ID, "login-button").click()
    
  def logout(self):
    self.driver.find_element(By.ID, "logout-button").click()   

3. alert 발생하는 시나리오에 처리하기

  • 기대되는 alert가 올바르게 발생하는지 확인

먼저 셀레니움 IDE를 사용하여 로그인에 실패하는 테스트케이스를 만듬

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def test_loginfail(self):
    self.driver.get("http://localhost:3000/")
    self.driver.set_window_size(1080, 1020)
    self.driver.find_element(By.LINK_TEXT, "무료로 시작하기").click()
    self.driver.find_element(By.ID, "emailInput").click()
    self.driver.find_element(By.ID, "emailInput").send_keys("test@example.com")
    self.driver.find_element(By.ID, "passwordInput").click()
    self.driver.find_element(By.ID, "passwordInput").send_keys("123456")
    self.driver.find_element(By.ID, "login-button").click()

    # time.sleep()을 이용하여 시간 지연을 삽입해야 함
    assert self.driver.switch_to.alert.text == "이메일 또는 비밀번호가 일치하지 않습니다."

    # 발생한 alert에 대해 확인 동작 추가
  • 수정한 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def test_loginfail(self):
    self.driver.get("http://localhost:3000/")
    self.driver.set_window_size(1080, 1020)
    self.driver.find_element(By.LINK_TEXT, "무료로 시작하기").click()
    self.driver.find_element(By.ID, "emailInput").click()
    self.driver.find_element(By.ID, "emailInput").send_keys("test@example.com")
    self.driver.find_element(By.ID, "passwordInput").click()
    self.driver.find_element(By.ID, "passwordInput").send_keys("123456")
    self.driver.find_element(By.ID, "login-button").click()

    # time.sleep()을 이용하여 시간 지연을 삽입해야 함
    # 발생한 alert에 대해 확인 동작 추가
    time.sleep(1)
    alert = self.driver.switch_to.alert
    assert alert.text == "이메일 또는 비밀번호가 일치하지 않습니다."
    alert.accept()

4. 파이썬을 사용하여 테스트

login fail 파일이 들어있는 폴더에서 다음 명령어를 입력하여 테스트 수행

1
python -m pytest
This post is licensed under CC BY 4.0 by the author.