Целью этой статьи является объяснение идей конструкции, а не полного исходного кода: 1. Сначала разберитесь с идеями, а затем систематизируйте исходный код; 2. Идеи в основном разрабатываются с учетом основной цели реализации, конструкции структуры, зависимости от окружающей среды, основных компонентов структуры и т. д.; 3. Применимыми объектами являются в основном студенты, которые плохо знакомы с тестированием автоматизации приложений; 4. Если вы ничего не понимаете, вы можете обсудить и поучиться друг у друга.
технология | Версия и описание |
---|---|
Python | V3.x (эта статья — 3.13.0) === Поддержка языков программирования |
Appium | Идентификация, расположение и работа органов управления |
BeautifulReport | Создать отчет о тестировании в формате HTML |
Logging | Python поставляется с === для создания журналов журналов. |
Unittest | Python поставляется с === платформой автоматического тестирования. |
Smtplib | Python поставляется с === почтовым сервисом |
Python поставляется с === почтовым сервисом | |
os | Python поставляется с системным модулем === |
PyCharm | Сообщество 2020.2, китайская версия |
Операционная система | Windows 10 Максимальная 64-разрядная версия |
другой | Последующие дополнения |
Из-за большого объема контента подробные шаги установки здесь не объясняются. Вы можете установить его самостоятельно. Необходимая среда установки следующая:
Создайте новую переменную системной среды JAVA_HOME;
Вставьте сюда описание изображенияИзменить системную переменную Путь: Для компьютеров с Windows 10 создайте новое значение переменной: %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; Для компьютеров с Windows 7 введите %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin в конце значения переменной. Обратите внимание, что они разделены знаком ;
Создайте новую системную переменную CLASSPATH: Имя переменной: CLASSPATH неопределенное Значение переменной: .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
D:\android-sdk-windows\platform-tools
D:\android-sdk-windows
D:\android-sdk-windows\tools
ANDROID_PATH
D:\android-sdk-windows\platform-tools
npm i --location=global appium
C:\Windows\System32>appium
[Appium] Welcome to Appium v2.2.3
[Appium] Appium REST http interface listener started on http://0.0.0.0:4723
[Appium] You can provide the following URLs in your client code to connect to this server:
[Appium] http://172.16.1.33:4723/
[Appium] http://127.0.0.1:4723/ (only accessible from the same host)
[Appium] http://172.31.32.1:4723/
[Appium] No drivers have been installed in C:\Users\Administrator\.appium. Use the "appium driver" command to install the one(s) you want to use.
C:\Windows\System32>appium-doctor
WARN AppiumDoctor [Deprecated] Please use appium-doctor installed with "npm install @appium/doctor --location=global"
info AppiumDoctor Appium Doctor v.1.16.2
info AppiumDoctor ### Diagnostic for necessary dependencies starting ###
info AppiumDoctor ✔ The Node.js binary was found at: D:\nodejs\node.EXE
info AppiumDoctor ✔ Node version is 20.10.0
info AppiumDoctor ✔ ANDROID_HOME is set to: D:\android-sdk-windows
info AppiumDoctor ✔ JAVA_HOME is set to: D:\jdk-11.0.8
info AppiumDoctor Checking adb, android, emulator, apkanalyzer.bat
info AppiumDoctor 'adb' is in D:\android-sdk-windows\platform-tools\adb.exe
info AppiumDoctor 'android' is in D:\android-sdk-windows\tools\android.bat
info AppiumDoctor 'emulator' is in D:\android-sdk-windows\tools\emulator.exe
info AppiumDoctor 'apkanalyzer.bat' is in D:\android-sdk-windows\platform-tools\apkanalyzer.bat
info AppiumDoctor ✔ adb, android, emulator, apkanalyzer.bat exist: D:\android-sdk-windows
info AppiumDoctor ✔ 'bin' subfolder exists under 'D:\jdk-11.0.8'
info AppiumDoctor ### Diagnostic for necessary dependencies completed, no fix needed. ###
info AppiumDoctor
info AppiumDoctor ### Diagnostic for optional dependencies starting ###
info AppiumDoctor ✔ opencv4nodejs is installed at: D:\nodejs\node_global. Installed version is: 5.6.0
info AppiumDoctor ✔ ffmpeg is installed at: D:\ffmpeg-6.1-essentials_build\bin\ffmpeg.EXE. ffmpeg version 6.1-essentials_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developers
info AppiumDoctor ✔ mjpeg-consumer is installed at: D:\nodejs\node_global. Installed version is: 2.0.0
info AppiumDoctor ✔ bundletool.jar is installed at: D:\android-sdk-windows\bundle-tools\bundletool.jar
info AppiumDoctor ✔ gst-launch-1.0.exe and gst-inspect-1.0.exe are installed at: F:\gstreamer\1.0\mingw_x86_64\bin\gst-launch-1.0.exe and F:\gstreamer\1.0\mingw_x86_64\bin\gst-inspect-1.0.exe
info AppiumDoctor ### Diagnostic for optional dependencies completed, no fix possible. ###
info AppiumDoctor
info AppiumDoctor Everything looks good, bye!
info AppiumDoctor
from appium import webdriver
from selenium.webdriver.common.by import By
class LoginPage:
def __init__(self, driver):
self.driver = driver
def open(self, app_path):
# Запустить приложение
desired_caps = {
'app': app_path,
# Другое желаемое capabilities...
}
self.driver.desired_capabilities.update(desired_caps)
self.driver.start_session()
def type_username(self, username):
# Введите имя пользователя
username_element = self.driver.find_element(By.ID, 'username_field')
username_element.clear()
username_element.send_keys(username)
def type_password(self, password):
# Введите пароль
password_element = self.driver.find_element(By.ID, 'password_field')
password_element.clear()
password_element.send_keys(password)
def click_login_button(self):
# Нажмите кнопку входа в систему
login_button = self.driver.find_element(By.ID, 'login_button')
login_button.click()
# Пример использования
# Предполагая, что «app_path» — это ваш путь к приложению.
app_path = '/path/to/your/app'
# Инициализировать драйвер Appium
driver = webdriver.Remote('http://localhost:4723/wd/hub')
# Инициализируйте класс LoginPage.
login_page = LoginPage(driver)
# Открыть приложение
login_page.open(app_path)
# Введите имя пользователь и пароль
login_page.type_username('your_username')
login_page.type_password('your_password')
# Нажмите кнопку входа в систему
login_page.click_login_button()
# Здесь можно добавить большеутверждениечтобы проверить, успешен ли вход в систему
Год, месяц, день, час, минута и секунда + _screen.png
# -*- coding:utf-8 -*-
# Автор: Ноама Нельсон
# Имя файла: screenShot.py
# Функция: инкапсулируйте функцию скриншота и вызовите ее.
import time
def save_creenshot(Windows):
now = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(time.time())) # Получить текущее время
pic_path = "../creenshot/"+now+'_screen.png' # Сохраните скриншот по указанному пути
Windows.get_screenshot_as_file(savePath=pic_path) # Функция скриншота
# -*- coding:utf-8 -*-
# Автор: Ноама Нельсон
# Имя файла: logOut.py
# Функция: функция инкапсуляции журнала
import logging # Представляем модуль журнала
import time
def log_out(log_dir, name_project):
'''
:log_dir : Путь журнала
:name_project : Название проекта=>Используется для именования журналов.
:return: никто
'''
now = time.strftime("%Y_%m_%d %H_%M_%S") # Получить текущее время,Формат:год месяц день час минута секунда
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename=log_dir + now + '-' + name_project + '_test_log.log',
filemode='w')
"""
level: Уровень журнала печати, ИНФОРМАЦИЯ: подробная; ВНИМАНИЕ: предупреждение; ОШИБКА: ошибка...
format: Используйте указанную строку формата для обработчика;
datefmt: использовать определенный формат времени и даты;
имя_файла: правила имени файла для журналов журналов;
filemode: режим чтения и записи файла.
"""
pip install BeautifulReport
;# -*- coding:utf-8 -*-
# Автор: Ноама Нельсон
# Имя файла: reportOut.py
# Функция: функция отчета о тестировании инкапсуляции
import time
import unittest
from BeautifulReport import BeautifulReport as bf # Представляем шаблон отчета BeautifulReport
def report_out(test_dir, report_dir, name_project):
'''
:test_dir: путь варианта использования
:report_dir : Путь отчета
:name_project : Название проекта=>Используется для именования и описания отчета.
:return: никто
'''
now = time.strftime("%Y_%m_%d %H_%M_%S")
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py') # Загрузить тестовые примеры
report_name = now + '-' + name_project + '_test_report.html' # Название отчета
run = bf(discover)
run.report(filename=report_name, report_dir=report_dir, описание=U"Регрессионный тест функции автоматизации пользовательского интерфейса Kugou Music")
"""
filename:Название отчета;
report_dir: путь хранения отчета о тестировании;
описание: описание отчета;
"""
# -*- coding:utf-8 -*-
# Автор: Ноама Нельсон
# Имя файла: sendMain.py
# Функция: инкапсулировать модуль почтового сервиса.
import time
import smtplib
import getpass
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import email
import os
def send_main(file_path, mail_to='yyy@126.com'):
mail_from = 'xxx@126.com'
f = open(file_path, 'rb')
mail_body = f.read()
f.close()
# msg = email.MIMEMultipart.MIMEMultipart()
msg = MIMEMultipart()
# Создайте объект MIMEBase как содержимое вложенного файла и прикрепите его к корневому контейнеру.
contype = 'application/octet-stream'
maintype, subtype = contype.split('/', 1)
# Чтение содержимого и формата файла
data = open(file_path, 'rb')
# file_msg = email.MIMEBase.MIMEBase(maintype, subtype)
file_msg = MIMEBase(maintype, subtype)
file_msg.set_payload(data.read())
data.close()
# email.Encoders.encode_base64(file_msg)
encoders.encode_base64(file_msg)
# Установить заголовок вложения
basename = os.path.basename(file_path)
file_msg.add_header('Content-Disposition', 'attachment', filename=basename)
msg.attach(file_msg)
print(u'msg Вложение успешно добавлено')
msg1 = MIMEText(mail_body, "html", 'utf-8')
msg.attach(msg1)
if isinstance(mail_to, str):
msg['To'] = mail_to
else:
msg['To'] = ','.join(mail_to)
msg['From'] = mail_from
msg['Subject'] = u'xxx автоматическое регрессионное тестирование'
msg['date'] = time.strftime('%Y-%m-%d-%H_%M_%S')
print(msg['date'])
smtp = smtplib.SMTP()
smtp.connect('smtp.126.com')
smtp.login('xxx@126.com', 'yyy') # Учетная запись и пароль для входа (паролем является ранее запрошенный код авторизации)
smtp.sendmail(mail_from, mail_to, msg.as_string())
smtp.quit()
print('email has send out !')
# -*- coding:utf-8 -*-
# Автор: Ноама Нельсон
# Имя файла: тулбар.py
# Функция: инкапсулировать элементы в сценарии использования (в основном панель инструментов Kugou Music).
from common.baseInfo import InitInfor
class ToolBar(object):
def __init__(self):
self.a = InitInfor()
self.kugou = self.a.kugou
def func_my_music(self):
return self.kugou.TableControl(Name="Моя музыка")
def func_find(self):
return self.kugou.TableControl(Name="Обнаружить")
def func_live(self):
return self.kugou.TableControl(Name="Прямая трансляция")
def func_explore(self):
return self.kugou.TableControl(Name="Исследовать")
def func_play(self):
return self.kugou.TableControl(Name="Mobile Play")
# утверждение
tool_bar = ["Моя музыка", "Обнаружить", «прямая трансляция», "исследовать", «Мобильная игра»]
# -*- coding:utf-8 -*-
# Автор: Ноама Нельсон
# Имя файла: test_toolbar.py
# Функция: перемещение по элементам музыкальной панели инструментов Kugou.
import unittest # Знакомство с фреймворком unittest
import time
from page.toolbar import ToolBar # Представляем элементы страницы
import logging
class TestToolBar(unittest.TestCase):
"""
Создать набор тестовых примеров
"""
def setUp(self):
self.toolbar = ToolBar() # создание экземпляра, вход в систему
self.kugou = self.toolbar.kugou # Вызов того же окна
self.log = logging.getLogger() # Инициализировать журнал
def tearDown(self):
self.toolbar.a.login_out() # Выйти из Музыки Куго
def test_toolbar(self):
""" Переключение между музыкальными инструментами Kugou """
self.log.info("======Панель инструментов Kugou======") # Добавить в журнал
time.sleep(0.5)
self.toolbar.func_my_music().Click()
self.toolbar.func_find().Click()
self.toolbar.func_live().Click()
self.toolbar.func_explore().Click()
self.toolbar.func_play().Click()
print("---------------", self.toolbar.func_play().Name)
self.assertIn(self.toolbar.func_my_music().Name, self.toolbar.tool_bar, «Сценарий использования выполнен успешно»).
print("Выполнение варианта использования ОК!")
if __name__ == "__main__":
unittest.main()
def acquire_report_address(reports_address):
# Все файлы в папке с отчетом о тестировании добавляются в список.
test_reports_list = os.listdir(reports_address)
# Создать новый список, отсортированный по возрастанию.
new_test_reports_list = sorted(test_reports_list)
# Получите последний отчет об испытаниях
the_last_report = new_test_reports_list[-1]
# Последний адрес отчета об испытаниях
the_last_report_address = os.path.join(reports_address, the_last_report)
return the_last_report_address
def run_case():
print("======Начать выполнение!!!======")
curpath = os.path.dirname(os.path.realpath(__file__))
report_dir = os.path.join(curpath, "report/") # Каталог хранения отчетов об испытаниях
test_dir = os.path.join(curpath, "testcase/") # Каталог чтения тестовых примеров
name_project = "KuGou "
report_out(test_dir, report_dir, name_project)
time.sleep(5)
print("======Выполнение завершено!!!======")
log_dir = os.path.join(curpath, "log/")
log_out(log_dir, name_project)
send_main(acquire_report_address(report_dir), mail_to=['xxx@qq.com']) # mail_to — кому отправлять,Вы можете написать соответствующий адрес электронной почты,Просто разделите их запятыми