๐Ÿ” Django ์„œ๋ฒ„ ์‹คํ–‰ ํ…Œ์ŠคํŠธํ•˜๊ธฐ (with selenium)

๋ชฉํ‘œ

  1. ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด selenium์˜ webdriver๋ฅผ ๊ฐ€๋™ํ•œ๋‹ค.
  2. ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด ๋กœ์ปฌ PC ์ƒ์˜ ์›น ํŽ˜์ด์ง€๋ฅผ ์—ฐ๋‹ค.
  3. ์›น ํŽ˜์ด์ง€ ํƒ€์ดํ‹€์— Django ๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

์ฒซ ๋ฒˆ์งธ ํ…Œ์ŠคํŠธ

from selenium import webdriver


browser = webdriver.Chrome()
browser.get('http://localhost:8000')

assert 'Django' in browser.title

์œ„ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด selenium์„ import ํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ํ•  ๊ฒƒ์ด๋‹ค. pip๋กœ selenium์„ ์„ค์น˜ํ•ด๋ณด์ž.

pip install -U selenium

selenium์„ ์ด์šฉํ•ด ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ์›น ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์„ค์น˜ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ ์ ˆํ•œ ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•˜์—ฌ ์›ํ•˜๋Š” ๊ณณ์— ์ €์žฅ์‹œํ‚ค์ž. ํ•„์ž๋Š” Chrome์„ ์ด์šฉํ•  ๊ฒƒ์ด๋ฏ€๋กœ ChromeDriver๋ฅผ ๋ฐ›์•˜๋‹ค.

๋“œ๋ผ์ด๋ฒ„ ์„ค์น˜๋ฅผ ์™„๋ฃŒํ–ˆ๋‹ค๋ฉด ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋ณด์ž.

selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH.

์œ„์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋œฌ๋‹ค๋ฉด ์›น ๋“œ๋ผ์ด๋ฒ„์˜ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ด์ฃผ์ง€ ์•Š์•„์„œ์ด๋‹ค. ์›น ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์ €์žฅํ•œ ์ƒ๋Œ€ ๊ฒฝ๋กœ๋‚˜ ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋„ฃ์–ด์ฃผ์ž.

browser = webdriver.Chrome('/path/to/chromedriver')

๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋ณด์ž.

Traceback (most recent call last):
  File "functional_test.py", line 11, in
    assert 'Django' in browser.title
AssertionError

ํฌ๋กฌ ์ฐฝ์ด ๋œจ๊ธด ํ•˜๋Š”๋ฐ ์‚ฌ์ดํŠธ ์—ฐ๊ฒฐ์ด ์•ˆ๋˜๊ณ  ์œ„ ์—๋Ÿฌ๊ฐ€ ๋‚˜ํƒ€๋‚œ๋‹ค๋ฉด Django ์„œ๋ฒ„๊ฐ€ ์ผœ์žˆ์ง€ ์•Š์•„์„œ์ด๋‹ค. ํ„ฐ๋ฏธ๋„์„ ํ•˜๋‚˜ ๋” ์ผœ์„œ Django ์„œ๋ฒ„๋ฅผ ์‹คํ–‰์‹œํ‚ค์ž.

python manage.py runserver

๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋ณด์ž.

์ •์ƒ์ ์œผ๋กœ Django ์›น ํŽ˜์ด์ง€๊ฐ€ ๋ณด์ธ๋‹ค. Title์— Django: the Web framework โ€ฆ ๋ผ๊ณ  ์“ฐ์—ฌ์žˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์œ„์—์„œ ์ž‘์„ฑํ•œ assert๋ฌธ(Title์— Django๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฌธ์žฅ)์ด True์—ฌ์•ผ ํ•œ๋‹ค. ํ„ฐ๋ฏธ๋„ ์ฐฝ์„ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ฌด๋Ÿฐ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ๋œจ์ง€ ์•Š์€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‘ ๋ฒˆ์งธ ํ…Œ์ŠคํŠธ

์ด๋ฒˆ์—๋Š” unittest ๋ชจ๋“ˆ์„ ์ด์šฉํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž.

from selenium import webdriver
import unittest


class DjangoTest(unittest.TestCase):
    def setUp(self):
        self.browser = webdriver.Chrome('/path/to/chromedriver')

    def tearDown(self):
        self.browser.quit()

    def test_can_start_django(self):
        self.browser.get('http://localhost:8000')

        self.assertIn('Django', self.browser.title)


if __name__ == '__main__':
    unittest.main()

์šฐ์„  unittest.TestCase๋ฅผ ์ƒ์†ํ•˜๋Š” ํด๋ž˜์Šค DjangoTest๋ฅผ ๋งŒ๋“ ๋‹ค. ํ…Œ์ŠคํŠธ์˜ ๋ฉ”์ธ ์ฝ”๋“œ๋Š” test_can_start_django() ๋ผ๋Š” ๋ฉ”์†Œ๋“œ์ด๋‹ค. setUp()๊ณผ tearDown()์€ ๊ฐ ํ…Œ์ŠคํŠธ ์‹œ์ž‘ ์ „๊ณผ ํ›„์— ์‹คํ–‰๋˜๋Š” ๋ฉ”์†Œ๋“œ๋กœ setUp์€ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์—ด ๋•Œ, tearDown์€ ๋‹ซ์„ ๋•Œ ์‚ฌ์šฉํ–ˆ๋‹ค. assertIn(a, b) ๋ฉ”์†Œ๋“œ๋Š” a in b๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฉ”์†Œ๋“œ์ด๋‹ค. ์œ„ ์ฝ”๋“œ๋กœ Django๋ผ๋Š” ํ…์ŠคํŠธ๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์˜ ํƒ€์ดํ‹€์— ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณด์ด๋Š”์ง€ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด Django ์„œ๋ฒ„๋ฅผ ๋„๊ณ  ์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด๋ณด์ž.

Traceback (most recent call last):
  File "functional_tests.py", line 19, in test_can_start_django
    self.assertIn('Django', self.browser.title)
AssertionError: 'Django' not found in 'localhost'
----------------------------------------------------------------------
Ran 1 test in 2.233s

FAILED (failures=1)

์ฒซ๋ฒˆ์งธ ์ฝ”๋“œ์™€ ๋น„๊ตํ•ด๋ณด๋ฉด ๋‘๋ฒˆ์งธ ์ฝ”๋“œ๊ฐ€ ์—๋Ÿฌ๊ฐ€ ์–ด๋–ค ํ•จ์ˆ˜์—์„œ ๋‚ฌ๋Š”์ง€ ๋˜ ๋ช‡ ๊ฐœ์˜ ํ…Œ์ŠคํŠธ์—์„œ ๋ช‡ ๊ฐœ๊ฐ€ ํ‹€๋ ธ๋Š”์ง€ ์ •ํ™•ํ•˜๊ฒŒ ์งš์–ด์ฃผ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ์ƒ๋Œ€๋กœ โ€˜Djangoโ€™ not found in โ€˜localhostโ€™ ๋ผ๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ๋ณด์ธ๋‹ค. ์ด๋ฒˆ์—” Django ์„œ๋ฒ„๋ฅผ ์ผœ๊ณ  ๋Œ๋ ค๋ณด์ž.

.
----------------------------------------------------------------------
Ran 1 test in 2.130s

OK

์„ฑ๊ณตํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ํ•œ๊ฐ€์ง€ ๋” ์ž‘์—…ํ•ด์ฃผ์–ด์•ผ ํ•  ๊ฒƒ์ด ์žˆ๋‹ค.

์•”๋ฌต์  ๋Œ€๊ธฐ ๊ธฐ๋Šฅ ์ถ”๊ฐ€

selenium์€ ๋น„๊ต์  ์•ˆ์ •์ ์œผ๋กœ ํŽ˜์ด์ง€ ๋กœ๋”ฉ์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜์ง€๋งŒ ์™„๋ฒฝํ•˜์ง„ ์•Š๋‹ค. implicitly_wait๋Š” ํ•„์š”์— ๋”ฐ๋ผ ์ง€์ •ํ•œ ์‹œ๊ฐ„๋งŒํผ ๋™์ž‘์„ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ๋‘˜ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ์€ 3์ดˆ๊ฐ„ ๋Œ€๊ธฐ ํ›„ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.

def setUp(self):
    self.browser = webdriver.Chrome('/path/to/chromedriver')
    self.browser.implicitly_wait(3)

References


Written by@ugaemi
Record things I want to remember

๐Ÿฑ GitHub๐Ÿ“š Reading Space