0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

「画像でゴミ分類!」アプリ作成日誌day9~テストの追加~

Posted at

一言でいうと

Djangoで作成したアプリにSeleniumを使ったテストを追加しました!

これまでの経緯

「画像でゴミ分類!」という画像を入れたらそれが何ゴミか分類してくれるwebアプリを作成しました。いったん完成していたのですが、テストが大事とかテスト駆動開発いいよねという記事に感化されてこのアプリにもテストを導入します。

<これまでの記事一覧>

テスト手法

Seleniumを使ったUIテストを行いたいので、DjangoのLiveServerTestCaseを利用します。

Jupyterで動作確認

Seleniumについてまだ勉強中なので、いきなりwebアプリ上に書くのではなく、Jupyterで挙動を確認しながらコードを書いていきます。

まずは、chromeを起動しましょう

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

DRIVER_PATH = r'chromedriver.exeのパス'

# ブラウザの起動
driver = webdriver.Chrome(executable_path=DRIVER_PATH)

そして開発用サーバーにアクセス。ここは開発用サーバーを立ち上げておく必要があります。

driver.get('http://localhost:8000/garbage')

まずは、タイトルを取得してみましょう

driver.title
# '画像でゴミ分類!'

次に、要素を取得してみましょう

driver.find_element_by_class_name("sample-img").get_attribute('outerHTML')
# '<img src="/static/garbage/media/gif/waiting.278078bec7bd.gif" alt="画像1" class="mt-3 sample-img waiting" id="waiting-gif">'

outerHTMLを見ると無事取得できていることがわかります。ただ、実はこのクラスに所属するものは複数あるので、そんなときはfind_elements_by_class_nameと複数形で使うとリストで取得できます。

len(driver.find_elements_by_class_name("sample-img"))
# 3

では画像をクリックする処理を書きます

driver.find_elements_by_class_name("sample-img")[1].click()

簡単ですね。

今度は遷移先のページでタグを取得してみます。

num_tr = len(driver.find_elements(By.XPATH, '//tr'))

書き方がちょっと変わりましたが、XML Pathで要素を指定しているだけで、やってることは同じですね。

これを用いてテストするには以下のようにすればいいです。

assert 6 == num_tr, "表の行数が一致しません"

では、一度トップページに戻って文字検索時のテストを書いていきます。
まずは、検索ボックスを取得してみましょう

driver.get('http://localhost:8000/garbage')
driver.find_elements(By.XPATH, '//input[@name="word"]')
# [<selenium.webdriver.remote.webelement.WebElement (session="d795b92e9edbbd43c50a2be08e0b75e1", element="54b9e56a-2624-4a33-9f5f-be8fe77a6e5e")>,
#  <selenium.webdriver.remote.webelement.WebElement (session="d795b92e9edbbd43c50a2be08e0b75e1", element="1ccd154e-326f-4e5c-8004-9258ec03bb39")>]

あれ、2つ出てくるのはなんででしょうか。これは、スマホ対応時のサイドバーとPC時の左メニューの分ですね。

PC時の左メニューのほうだけを使います。文字列として針を入力してみましょう。

search_box = driver.find_elements(By.XPATH, '//input[@name="word"]')[1]
search_box.send_keys('')

そして、Enterキーを押します。この後は先ほどと同じく表の行数をチェックするようにしようかと思います。

search_box.send_keys(Keys.ENTER)
len(driver.find_elements(By.XPATH, '//tr'))
# 14

testコードの追加

これまで書いたコードをwebアプリ上に移植します。
まず、test.pyを削除してその代わりにtests/test_views.pyを追加します。
まずはおまじないです。LiveServerTestCaseクラスをオーバーライドしてドライバーなどの場所を教えます。

from django.test import LiveServerTestCase
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys


class TestClickSample(LiveServerTestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.selenium = WebDriver(executable_path=r'garbage\tests\chromedriver.exe')

    @classmethod
    def tearDownClass(cls):
        cls.selenium.quit()
        super().tearDownClass()

まずは、ページを開いてタイトルがあってるかを確認をしておきましょう。

    def test_open_page(self):
        """ページを開いてタイトルがあってるかを確認
        """
        self.selenium.get('http://localhost:8000/garbage')
        self.assertEquals("画像でゴミ分類!", self.selenium.title)

次にサンプル画像をクリックしたときの処理を記述して、モデルの挙動が正しいかを確認できるようにします。

    def test_click_sample(self):
        """モデルの動きが正常かを確認
        サンプル画像をクリックした際の挙動を確認
        """
        self.selenium.get('http://localhost:8000/garbage')
        self.selenium.find_elements_by_class_name("sample-img")[1].click()

        num_tr = len(self.selenium.find_elements(By.XPATH, '//tr'))
        self.assertEquals(6, num_tr)

最後に文字検索時の挙動をテストします。

    def test_search(self):
        """文字検索時の挙動をテスト
        """
        self.selenium.get('http://localhost:8000/garbage')
        search_box = self.selenium.find_elements(By.XPATH, '//input[@name="word"]')[1]
        search_box.send_keys('')
        search_box.send_keys(Keys.ENTER)

        num_tr = len(self.selenium.find_elements(By.XPATH, '//tr'))
        self.assertEquals(14, num_tr)

テスト実行してみましょう。

Creating test database for alias 'default'...
System check identified no issues (0 silenced).

----------------------------------------------------------------------
Ran 3 tests in 10.380s

OK

無事テストが通ったようです!

参考文献

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?