[Начало работы] Идеи по созданию среды автоматического тестирования пользовательского интерфейса приложений и мобильных устройств на основе Python+Unittest+Appium+Excel+BeautifulReport
[Начало работы] Идеи по созданию среды автоматического тестирования пользовательского интерфейса приложений и мобильных устройств на основе Python+Unittest+Appium+Excel+BeautifulReport

Целью этой статьи является объяснение идей конструкции, а не полного исходного кода: 1. Сначала разберитесь с идеями, а затем систематизируйте исходный код; 2. Идеи в основном разрабатываются с учетом основной цели реализации, конструкции структуры, зависимости от окружающей среды, основных компонентов структуры и т. д.; 3. Применимыми объектами являются в основном студенты, которые плохо знакомы с тестированием автоматизации приложений; 4. Если вы ничего не понимаете, вы можете обсудить и поучиться друг у друга.

1 Удовлетворение целей и потребностей

1.1 Достичь цели

  • Имитировать действия пользователя (мышь, клавиатура) для быстрого и многократного выполнения тестовых случаев;
  • Облегчает регрессионное тестирование и быстро охватывает основные варианты использования или функции;
  • Онлайн- или офлайн-проверка и тестирование в сочетании с непрерывной интеграцией позволяют своевременно обнаруживать проблемы в операционной среде;
  • личное совершенствование Автоматизированное Возможности современной технологии предоставляют мощные средства тестирования для бизнеса. 1.2 Функциональные требования
  • На основе Unittest все тестовые сценарии инкапсулируются, вызываются, организуются и выполняются пакетами или заданными тестовыми примерами;
  • Поддерживает службу электронной почты, вы можете добавить адрес электронной почты любого члена команды, чтобы оперативно уведомлять членов команды о результатах операции автоматизации;
  • Поддерживает журналы для сохранения всех данных или данных, которые необходимо записывать во время запущенного процесса;
  • Поддерживает отчеты о тестировании в формате HTML для визуального отображения результатов и данных испытаний;
  • Поддерживает разделение вариантов использования и результатов тестирования для облегчения управления данными;
  • Поддерживает инкапсуляцию входа пользователя, и все последующие входы в систему используют общий метод;
  • Поддерживает произвольную модификацию Beautifulreport и настраиваемые шаблоны отчетов об испытаниях;
  • Поддержка многоязычных отчетов об испытаниях (английский и китайский);
  • Поддержка функции скриншота;
  • Поддержка непрерывной интеграции Jenkins. 2 Инструкции по проектированию каркаса 2.1 Анализ требований|Функция| Описание| |--|--| |Использовать фреймворк Unittest | Открытый исходный код Автоматизированное фреймворк, используйте его напрямую | |Запуск в пакетном режиме или в определенных случаях использования | Платформа Unittest может поддерживать эту функцию. | |журнал журнала | Просто используйте библиотеку журналирования Python. | |Создать отчет о тестировании HTML | Эту функциональность можно реализовать с помощью модуля BeautifulReport. | |Разделение проекта варианта использования и результатов | режим ПО | |Пакет входа пользователя | Непосредственно модульная функция входа в систему и использование настройки и демонтажа в среде Unittest. | |Индивидуальный шаблон отчета об испытаниях | Использование модуля BeautifulReport | |Отчет на нескольких языках | Использование модуля BeautifulReport | |Функция создания снимков экрана | Использование метода CaptureToImage UIAutomation |

2.2 Стек технологий

технология

Версия и описание

Python

V3.x (эта статья — 3.13.0) === Поддержка языков программирования

Appium

Идентификация, расположение и работа органов управления

BeautifulReport

Создать отчет о тестировании в формате HTML

Logging

Python поставляется с === для создания журналов журналов.

Unittest

Python поставляется с === платформой автоматического тестирования.

Smtplib

Python поставляется с === почтовым сервисом

email

Python поставляется с === почтовым сервисом

os

Python поставляется с системным модулем ===

PyCharm

Сообщество 2020.2, китайская версия

Операционная система

Windows 10 Максимальная 64-разрядная версия

другой

Последующие дополнения

2.3 Каркасная конструкция

3 Описание зависимости от среды

Из-за большого объема контента подробные шаги установки здесь не объясняются. Вы можете установить его самостоятельно. Необходимая среда установки следующая:

3.1 Установка Python

  • В соответствии с вашими потребностями в этой статье используется версия 3.13.0;
  • Обратите внимание, что в процессе установки в систему автоматически добавляются переменные check pip и среды;
  • Установка происходит следующим образом;
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
    rmУстановить
  • Установите его самостоятельно и после установки загрузите языковой пакет на китайскую версию;
  • Интерфейс выглядит следующим образом:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
    um-Inspector
  • Непосредственный поиск веб-версии Appium-Inspector в Интернете;
  • Откройте его напрямую следующим образом:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
  • Desired Некоторые параметры конфигурации возможностей можно обозначить следующим образом:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения

3.4 Конфигурация установки JDK

  • Загрузите необходимый JDK и выберите соответствующую Операционная. версии системы достаточно;
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
  • Не забудьте настроить переменные среды:

Создайте новую переменную системной среды 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

  • Проверьте среду Java, например введите java в cmd. Следующее указывает на нормальную установку:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения

3.5 Загрузка SDK

  • Выберите соответствующий SDK для загрузки следующим образом:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
  • После загрузки распакуйте его в указанный каталог, например:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
  • Настройте инструменты платформы, корневой каталог и инструменты SDK в путь к переменной системной среды (установленный в соответствии с вашим собственным путем):
Язык кода:python
кодКоличество запусков:0
копировать
D:\android-sdk-windows\platform-tools
D:\android-sdk-windows
D:\android-sdk-windows\tools

3.6 Настройка среды Android

  • Создайте новую переменную системной среды ANDROID_HOME, значением которой является корневой каталог SDK ANDROID_HOME; D:\android-sdk-windows
  • Создайте новую переменную системной среды ANDROID_PATH, значением которой является каталог инструментов платформы SDK:
Язык кода:python
кодКоличество запусков:0
копировать
ANDROID_PATH
D:\android-sdk-windows\platform-tools

3.7 Установка NodeJs

  • Чтобы установить это, вам нужно использовать его только для установки Appium и проверить, прошла ли последующая установка Appium успешно;
  • После загрузки дважды щелкните, чтобы запустить node-v20.10.0-x64.msi;
  • После установки выполните npm в командной строке и увидите следующий интерфейс, что означает, что установка узла прошла успешно:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
    ppium
  • Установите с помощью NPM:
Язык кода:python
кодКоличество запусков:0
копировать
npm i --location=global appium
  • Просто введите appium в командной строке:
Язык кода:python
кодКоличество запусков:0
копировать
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.
  • проверка среды appium:
Язык кода:python
кодКоличество запусков:0
копировать
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

4 О позиционировании элемента

4.1 позиционирование uiautomatorviewer

  • uiautomatorviewer находится в каталоге Tools\ каталога SDK;
  • Например, у меня: D:\android-sdk-windows\tools:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
  • Дважды щелкните uiautomatorviewer.bat, чтобы начать:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
    omator + таргетинг accessibility_id
  • После открытия uiautomatorviewer импортируйте файлы uix и png:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
  • таргетинг accessibility_id в основном использует содержимое содержимого элемента, а именно:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения

5 Конструкция рамной конструкции

5.1 Вход в пакет

  • Щелкните правой кнопкой мыши в каталоге проекта-[Новый]-[Python. Package] создайте новый пакет с именем common;
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
  • Щелкните правой кнопкой мыши общий-[Новый]-[Python. file] с именем baseInfo.py, каталог проекта выглядит следующим образом:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
  • Инкапсулированный метод входа:
Язык кода:python
кодКоличество запусков:0
копировать
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()
 
# Здесь можно добавить большеутверждениечтобы проверить, успешен ли вход в систему

5.2 Функция снимка экрана и вызов

  • Нажмите [common]-[New]-[Python File], чтобы создать новый py-файл с именем creenShot;
  • Правила именования для названий скриншотов:

Год, месяц, день, час, минута и секунда + _screen.png

  • Код функции скриншота:
Язык кода:python
кодКоличество запусков:0
копировать
# -*- 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)                      # Функция скриншота
  • Просто вызывайте этот метод напрямую в других местах, где нужны скриншоты.

5.3 Инкапсуляция модуля журнала

  • Нажмите [common]-[New]-[Python File], чтобы создать новый py-файл с именем logOut, который используется для инкапсуляции журнала журнала;
  • Откройте новый файл logOut.py и создайте новый метод log_out для инкапсуляции журнала. Метод log_out принимает два параметра: один — имя проекта, а другой — путь хранения журнала.
Язык кода:python
кодКоличество запусков:0
копировать
# -*- 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: режим чтения и записи файла.
    """

5.4 Упаковка модуля протокола испытаний

  • Используйте напрямуюpip install BeautifulReport;
  • Нажмите [common]-[New]-[Python File], чтобы создать новый py-файл с именем reportOut, который используется для инкапсуляции отчета о тестировании;
Язык кода:python
кодКоличество запусков:0
копировать
# -*- 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: путь хранения отчета о тестировании;
    описание: описание отчета;
    """

5.5 Упаковка модуля почтового сервиса

  • Цель состоит в том, чтобы правильно настроить клиент сторонней службы электронной почты, просто найдите метод настройки напрямую;
  • Нажмите [common]-[New]-[Python File], чтобы создать новый py-файл с именем sendMain, который используется для инкапсуляции почтовой службы;
Язык кода:python
кодКоличество запусков:0
копировать
# -*- 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 !')

5.6 Разработка сценария использования автоматизации

  • В каталоге проекта создайте новый пакет Python с именем page;
  • Создайте новый пакет с именем testcase в каталоге проекта;
  • На странице в основном хранятся методы общедоступной страницы, такие как:
Язык кода:python
кодКоличество запусков:0
копировать
# -*- 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 = ["Моя музыка", "Обнаружить", «прямая трансляция», "исследовать", «Мобильная игра»]
  • Создайте новый тестовый пример в пакете testcase и вызовите метод страницы:
Язык кода:python
кодКоличество запусков:0
копировать
# -*- 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()

5.7 каркас главного входаmain.pyдизайн&Отчет о тестировании звонков

  • Создайте новый py-файл с именем mian в каталоге проекта;
  • Создайте новый каталог отчетов в каталоге проекта для хранения отчетов об испытаниях;
  • Откройте main.py и сначала создайте сценарий для чтения последнего отчета о тестировании в каталоге отчетов;
Язык кода:python
кодКоличество запусков:0
копировать
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
  • Отчет о проверке звонка;
Язык кода:python
кодКоличество запусков:0
копировать
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 в каталоге проекта для хранения журналов;
  • Журнал вызовов в методе run_case;
Язык кода:python
кодКоличество запусков:0
копировать
log_dir = os.path.join(curpath, "log/") 
log_out(log_dir, name_project)
  • Вызывается в методе run_case;
Язык кода:python
кодКоличество запусков:0
копировать
send_main(acquire_report_address(report_dir), mail_to=['xxx@qq.com']) # mail_to — кому отправлять,Вы можете написать соответствующий адрес электронной почты,Просто разделите их запятыми

6 Эффект операции

  • Эффект журнала:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
  • Отчет об испытаниях:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
  • Эффект электронной почты:
    Вставьте сюда описание изображения
    Вставьте сюда описание изображения
boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода