[Django] Channels 사용하기 - 4
2022. 10. 24. 17:31ㆍTIL/Django
이 글은 [Django] Channels 사용하기 - 3에서 이어집니다.
views 테스트하기
Selenium을 사용하여 end-to-end 테스트를 할 것이다.
- 메시지를 보낼 때, 같은 방에 있는 모두가 그 메시지를 보는가
- 메시지를 보낼 떄, 다른 방에 있는 누군가는 메시지를 볼 수 없는가
Selenium을 설치하자
$ python3 -m pip install selenium
chat/tests.py
파일을 만들고 코드를 작성하자.
# chat/tests.py
from channels.testing import ChannelsLiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys # 키보드의 키 명령 모음
from selenium.webdriver.support.wait import WebDriverWait
class ChatTests(ChannelsLiveServerTestCase):
serve_static = True # emulate StaticLiveServerTestCase
@classmethod
def setUpClass(cls):
"""
Set up configuration
"""
super().setUpClass()
try:
# NOTE: Requires "chromedriver" binary to be installed in $PATH
cls.driver = webdriver.Chrome("chromedriver가 깔린 path 입력")
except:
super().tearDownClass()
raise
@classmethod
def tearDownClass(cls) -> None:
"""
Delete configuration
"""
cls.driver.quit()
super().tearDownClass()
def test_when_chat_message_posted_then_seen_by_everyone_in_same_room(self):
try:
self._enter_chat_room("room_1")
self._open_new_window()
self._enter_chat_room("room_1")
self._switch_to_window(0)
self._post_message("hello")
WebDriverWait(self.driver, 2).until(
lambda _: "hello" in self._chat_log_value,
"Message was not received by window 1 from window 1",
)
self._switch_to_window(1)
WebDriverWait(self.driver, 2).until(
lambda _: "hello" in self._chat_log_value,
"Message was not received by window 2 from window 1",
)
finally:
self._close_all_new_windows()
def test_when_chat_message_posted_then_not_seen_by_anyone_in_different_room(self):
try:
self._enter_chat_room("room_1")
self._open_new_window()
self._enter_chat_room("room_2")
self._switch_to_window(0)
self._post_message("hello")
WebDriverWait(self.driver, 2).until(
lambda _: "hello" in self._chat_log_value,
"Message was not received by window 1 from window 1",
)
self._switch_to_window(1)
self._post_message("world")
WebDriverWait(self.driver, 2).until(
lambda _: "world" in self._chat_log_value,
"Message was not received by window 2 from window 2",
)
self.assertTrue(
"hello" not in self._chat_log_value,
"Message was improperly received by window 2 from window 1",
)
finally:
self._close_all_new_windows()
# === Utility ===
def _enter_chat_room(self, room_name):
self.driver.get(self.live_server_url + "/chat/")
ActionChains(self.driver).send_keys(room_name, Keys.ENTER).perform()
WebDriverWait(self.driver, 2).until(
lambda _: room_name in self.driver.current_url
)
def _open_new_window(self):
self.driver.execute_script('window.open("about:blank", "_blank");')
self._switch_to_window(-1)
def _close_all_new_windows(self):
while len(self.driver.window_handles) > 1:
self._switch_to_window(-1)
self.driver.execute_script("window.close();")
if len(self.driver.window_handles) == 1:
self._switch_to_window(0)
def _switch_to_window(self, window_index):
self.driver.switch_to.window(self.driver.window_handles[window_index])
def _post_message(self, message):
ActionChains(self.driver).send_keys(message, Keys.ENTER).perform()
@property
def _chat_log_value(self):
return self.driver.find_element(
by=By.CSS_SELECTOR, value="#chat-log"
).get_property("value")
django에서는 테스트를 위한 데이터베이스로 in-memory 데이터베이스인 sqlite3
를 사용하고 있으므로 테스트가 잘 실행되지 않을 것이다. 따라서 테스트를 실행하기 위해 sqlite3
데이터베이스가 메모리에 있을 필요가 없다고 프로젝트에 알려야 한다. socket_channels/settings.py
에 다음과 같이 수정하자.
# socket_channels/settings.py
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
"TEST": {
"NAME": BASE_DIR / "db.sqlite3",
},
}
}
이제 테스트를 실행해 보자.
$ python3 manage.py test chat.tests
반응형
'TIL > Django' 카테고리의 다른 글
[Django] Channels 사용하기 - 3 (0) | 2022.10.24 |
---|---|
[Django] Channels 사용하기 - 2 (2) | 2022.10.18 |
[Django] Channels 사용하기 - 1 (3) | 2022.10.17 |
[Django] connection.queries always empty (0) | 2022.10.13 |
[Django] DRF란? (0) | 2022.10.12 |