From 0a63c5354a67ccbf9084305506442d6475e8663a Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Tue, 9 Apr 2024 12:11:30 +0800 Subject: [PATCH 1/6] Make test_add_word.py work again --- .gitignore | 2 ++ README.md | 17 ++++++++++ app/test/conftest.py | 4 +-- app/test/helper.py | 33 ++++++++++++++++++ app/test/test_add_word.py | 71 +++++++-------------------------------- 5 files changed, 66 insertions(+), 61 deletions(-) create mode 100644 app/test/helper.py diff --git a/.gitignore b/.gitignore index 34e28e4..74c23e3 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,6 @@ app/db/wordfreqapp.db app/static/donate-the-author.jpg app/static/donate-the-author-hidden.jpg app/model/__pycache__/ +app/test/__pycache__/ +app/test/.pytest_cache/ app/log.txt diff --git a/README.md b/README.md index 77f25fa..03a130a 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,23 @@ We welcome feedback on EnglishPal. Feedback examples: EnglishPal's bugs and improvement suggestions are recorded in [Bugzilla](http://118.25.96.118/bugzilla/buglist.cgi?bug_status=__all__&list_id=1302&order=Importance&product=EnglishPal&query_format=specific). Send (lanhui at zjnu.edu.cn) an email message for opening a Bugzilla account or reporting a bug. +## End-to-end testing + +We use the Selenium test framework to test our app. + +In order to run the test, first we need to download a webdriver executable. + +Microsoft Edge's webdriver can be downloaded from [microsoft-edge-tools-webdriver](https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/). Make sure the version we download matches the version of the web browser installed on our laptop. + +After extracting the downloaded zip file (e.g., edgedriver_win64.zip), rename msedgedriver.exe to MicrosoftWebDriver.exe. + +Add MicrosoftWebDriver.exe's path to system's PATH variable. + +Install the following dependencies too: + +- pip install -U selenium==3.141.0 +- pip install -U urllib3==1.26.2 + ## TODO diff --git a/app/test/conftest.py b/app/test/conftest.py index 29f6431..460480d 100644 --- a/app/test/conftest.py +++ b/app/test/conftest.py @@ -1,6 +1,5 @@ import pytest from selenium import webdriver -from selenium.webdriver.common.desired_capabilities import DesiredCapabilities @pytest.fixture def URL(): @@ -9,5 +8,4 @@ def URL(): @pytest.fixture def driver(): - my_driver = webdriver.Edge() # uncomment this line if you wish to run the test on your laptop - return my_driver + return webdriver.Edge() # uncomment this line if you wish to run the test on your laptop diff --git a/app/test/helper.py b/app/test/helper.py new file mode 100644 index 0000000..c8492a0 --- /dev/null +++ b/app/test/helper.py @@ -0,0 +1,33 @@ +import uuid +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from selenium.common.exceptions import UnexpectedAlertPresentException, NoAlertPresentException + +def signup(URL, driver): + username = 'TestUser' + str(uuid.uuid1()).split('-')[0].title() + password = '[Abc+123]' + + driver.get(URL) + + elem = driver.find_element_by_link_text('注册') + elem.click() + + elem = driver.find_element_by_id('username') + elem.send_keys(username) + + elem = driver.find_element_by_id('password') + elem.send_keys(password) + + elem = driver.find_element_by_id('password2') + elem.send_keys(password) + + elem = driver.find_element_by_class_name('btn') # 找到"登录"按钮 + elem.click() + + try: + WebDriverWait(driver, 1).until(EC.alert_is_present()) + driver.switch_to.alert.accept() + except (UnexpectedAlertPresentException, NoAlertPresentException): + pass + + return username, password diff --git a/app/test/test_add_word.py b/app/test/test_add_word.py index a08c376..ed64899 100644 --- a/app/test/test_add_word.py +++ b/app/test/test_add_word.py @@ -1,76 +1,31 @@ -# -*- coding: utf-8 -*- -# Run the docker image using the following command: -# docker run -d -p 4444:4444 selenium/standalone-chrome -from selenium import webdriver -from selenium.webdriver.common.desired_capabilities import DesiredCapabilities - -import random, time -import string - -driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) -driver.implicitly_wait(10) - -HOME_PAGE = 'http://121.4.94.30:91/' +import time +from helper import signup -def has_punctuation(s): - return [c for c in s if c in string.punctuation] != [] - -def test_add_word(): +def test_add_word(URL, driver): try: - driver.get(HOME_PAGE) - assert 'English Pal -' in driver.page_source - - # login - elem = driver.find_element_by_link_text('登录') - elem.click() - - uname = 'lanhui' - password = 'l0ve1t' - elem = driver.find_element_by_name('username') - elem.send_keys(uname) - - elem = driver.find_element_by_name('password') - elem.send_keys(password) - - elem = driver.find_element_by_xpath('//form[1]/p[3]/input[1]') # 找到登录按钮 - elem.click() - - assert 'EnglishPal Study Room for ' + uname in driver.title - - # get essay content - elem = driver.find_element_by_id('text-content') - essay_content = elem.text - - elem = driver.find_element_by_id('selected-words') - word = random.choice(essay_content.split()) - while 'font>' in word or 'br>' in word or 'p>' in word or len(word) < 6 or has_punctuation(word): - word = random.choice(essay_content.split()) + username, password = signup(URL, driver) # sign up a new account and automatically log in + time.sleep(1) + # enter the word in the text area + elem = driver.find_element_by_id('selected-words') + word = 'devour' elem.send_keys(word) - elem = driver.find_element_by_xpath('//form[1]//input[1]') # 找到get所有词频按钮 + elem = driver.find_element_by_xpath('//form[1]//button[1]') # 找到"把生词加入我的生词库"按钮 elem.click() - - elems = driver.find_elements_by_xpath("//input[@type='checkbox']") - for elem in elems: - if elem.get_attribute('name') == 'marked': - elem.click() - + elem = driver.find_element_by_name('add-btn') # 找到加入我的生词簿按钮 elem.click() - driver.refresh() - driver.refresh() - driver.refresh() elems = driver.find_elements_by_xpath("//p[@class='new-word']/a") - + found = 0 for elem in elems: if word in elem.text: found = 1 break - + assert found == 1 - finally: + finally: driver.quit() From a4608db424b98cc72506d9dc1f5628ca07ba4834 Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Tue, 9 Apr 2024 13:21:44 +0800 Subject: [PATCH 2/6] Correct code comments --- app/test/helper.py | 2 +- app/test/test_add_word.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/test/helper.py b/app/test/helper.py index c8492a0..2b0deec 100644 --- a/app/test/helper.py +++ b/app/test/helper.py @@ -21,7 +21,7 @@ def signup(URL, driver): elem = driver.find_element_by_id('password2') elem.send_keys(password) - elem = driver.find_element_by_class_name('btn') # 找到"登录"按钮 + elem = driver.find_element_by_class_name('btn') # 找到"注册"按钮 elem.click() try: diff --git a/app/test/test_add_word.py b/app/test/test_add_word.py index ed64899..6526bf0 100644 --- a/app/test/test_add_word.py +++ b/app/test/test_add_word.py @@ -15,7 +15,7 @@ def test_add_word(URL, driver): elem = driver.find_element_by_xpath('//form[1]//button[1]') # 找到"把生词加入我的生词库"按钮 elem.click() - elem = driver.find_element_by_name('add-btn') # 找到加入我的生词簿按钮 + elem = driver.find_element_by_name('add-btn') # 找到"加入我的生词簿"按钮 elem.click() elems = driver.find_elements_by_xpath("//p[@class='new-word']/a") From 0dc253bc1982dcfad21abede5d75c5a52d20123a Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Tue, 9 Apr 2024 15:58:47 +0800 Subject: [PATCH 3/6] Ignore pytest_report.html --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 74c23e3..5d0346a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ app/static/donate-the-author-hidden.jpg app/model/__pycache__/ app/test/__pycache__/ app/test/.pytest_cache/ +app/test/pytest_report.html app/log.txt From 083cbfd0405fce0db8b1302fe6a1163a6d4b2023 Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Tue, 9 Apr 2024 16:01:44 +0800 Subject: [PATCH 4/6] Ignore app/test/assets --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5d0346a..33f789d 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,5 @@ app/model/__pycache__/ app/test/__pycache__/ app/test/.pytest_cache/ app/test/pytest_report.html +app/test/assets app/log.txt From 4f91659713fa7ee5aa83aa1f34f904307ae382c5 Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Tue, 9 Apr 2024 16:13:05 +0800 Subject: [PATCH 5/6] How to run pytest --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 03a130a..bbe4bb4 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,9 @@ Install the following dependencies too: - pip install -U selenium==3.141.0 - pip install -U urllib3==1.26.2 +Run the test using pytest as follows: pytest --html=pytest_report.html test_add_word.py + +The above command will generate a HTML report file pytest_report.html after finishing executing test_add_word.py. Note: you need to install pytest-html package first: pip install pytest-html. ## TODO From 77a3adb5465b968942d7e8b5fa4f93c2f5ced782 Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Tue, 9 Apr 2024 20:06:30 +0800 Subject: [PATCH 6/6] Define fixture 'restore_sqlite_database' that will be automatically used to restore the database before starting each test --- app/test/conftest.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/test/conftest.py b/app/test/conftest.py index 460480d..fe64e5c 100644 --- a/app/test/conftest.py +++ b/app/test/conftest.py @@ -1,4 +1,5 @@ import pytest +import sqlite3 from selenium import webdriver @pytest.fixture @@ -9,3 +10,17 @@ def URL(): @pytest.fixture def driver(): return webdriver.Edge() # uncomment this line if you wish to run the test on your laptop + + +@pytest.fixture(autouse=True) +def restore_sqlite_database(): + ''' + Automatically restore SQLite database file app/db/wordfreqapp.db + using SQL statements from app/static/wordfreqapp.sql + ''' + con = sqlite3.connect('../db/wordfreqapp.db') + with con: + con.executescript('DROP TABLE IF EXISTS user;') + con.executescript('DROP TABLE IF EXISTS article;') + con.executescript(open('../static/wordfreqapp.sql', encoding='utf8').read()) + con.close()