GithubHelp home page GithubHelp logo

linuxdeepin / youqu Goto Github PK

View Code? Open in Web Editor NEW
40.0 4.0 9.0 45.56 MB

YouQu, a simple and powerful autotest framework.

Home Page: https://linuxdeepin.github.io/youqu/

License: GNU General Public License v2.0

Shell 2.43% Python 90.68% Meson 0.02% CMake 0.31% C++ 1.49% C 5.08%

youqu's Introduction

YouQu

YouQu(有趣),一个使用简单且功能强大的自动化测试基础框架。

GitHub issues PyPI Static Badge

Downloads Hits


深度社区:linuxdeepin | deepin-community

欧拉社区:src-openeuler

官方文档:https://youqu.uniontech.com

欢迎加入 YouQu官方兴趣小组


YouQu(有趣)是统信公司(Deepin/UOS)开源的一个 Linux 操作系统的自动化测试框架,支持多元化元素定位和断言、用例标签化管理和执行、强大的日志和报告输出等特色功能,同时完美兼容 X11、Wayland 显示协议,环境部署简单,操作易上手。🔥

  • 💻 Linux 桌面应用 UI 自动化测试
  • 🌏 Web UI 自动化测试
  • 🚌 Linux DBus 接口自动化测试
  • 🚀 命令行自动化测试
  • 🕷️ HTTP 接口自动化测试
  • ⏲️ Linux 桌面应用性能自动化测试
  • 💥 Fuzzy Desktop 桌面模糊测试

从 PyPI 安装:

$ sudo pip3 install youqu
不加 sudo ?

不加 sudo 也可以:

pip3 install youqu

但可能出现 youqu-startproject 命令无法使用;

这是因为不加 sudo 时,youqu-startproject 命令会生成在 $HOME/.local/bin 下,

而此路径可能不在环境变量(PATH)中,因此您需要添加环境变量:

export PATH=$PATH:$HOME/.local/lib

您可以在任意目录下,使用 youqu-startproject 命令创建一个项目:

$ youqu-startproject my_project

注意:所有命令不要以 root 用户执行!

如果 youqu-startproject 后面不加参数,默认的项目名称为:youqu

安装部署 YouQu 执行所需环境:

$ cd my_project
$ bash env.sh
# 使用的默认密码是 1;
# 您可以使用 -p 选项传入密码:bash env.sh -p ${my_password};
# 也可以修改配置文件 setting/globalconfig.ini 里面的 PASSWORD 配置项;

使用 startapp 命令自动创建 APP 工程:

$ youqu manage.py startapp autotest_deepin_some

自动创建的 APP 工程遵循完整的 PO 设计模式,让你可以专注于用例和方法的编写维护。

apps 目录下会自动创建一个 APP 工程:autotest_deepin_some,同时新建好工程模板目录和模板文件:

my_project
├── apps
│   ├── autotest_deepin_some  # <-- APP工程
...     ├── ...

在你的远程 Git 仓库中,只需要保存 APP 工程这部分代码即可。

autotest_deepin_some 是你的 APP 工程名称,在此基础上,你可以快速的开始你的 AT 项目,更重要的是确保创建工程的规范性。

apps 目录下可以存在任意多个 APP 工程。

在项目根目录下有一个 manage.py ,它是一个执行器入口,提供了本地执行、远程执行等的功能。

$ youqu manage.py run

在一些 CI 环境下使用命令行参数会更加方便:

$ youqu manage.py run -a apps/autotest_deepin_some -k "xxx" -t "yyy"

更多用法可以使用 -h--help 查看。

通过配置文件配置参数

在配置文件 setting/globalconfig.ini 里面支持配置对执行的一些参数进行配置。

远程执行就是用本地作为服务端控制远程机器执行,远程机器执行的用例相同。

使用 remote 命令:

$ youqu manage.py remote

贡献文档

YouQu 在 GPL-2.0 下发布。

youqu's People

Contributors

003307 avatar darklii avatar mikigo avatar saifeilee avatar zhao-george avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

youqu's Issues

uos 系统uos id使用youqu框架方法无法登陆

环境:专业版1060update2 wayland 架构
问题描述:商店触发登陆uos id,使用"input_message"方法无法向输入框输入账号密码,走到此步骤“"kill -9 $(pidof wayland_autotool)",登陆弹框就会卡死在那,光标消失
image

文档增加各种驱动模式章节

  • 指定执行某一个用例
  • 指定某个目录执行
  • 执行某个APP工程的所有用例
  • 根据关键词执行
  • 根据标签执行
  • 批量用例ID驱动执行
  • 测试单驱动执行
  • 测试套驱动执行
  • 本地用例文件驱动执行

auto_uos安装问题

最近在做 aarch64架构+wayland的UOS系统自动化
auto_uos这个工具是闭源的不,根据文档在执行env.sh的时候提示安装失败,查看sh脚本内部的镜像地址似乎是一个内网地址~
这个库是有另外独立发布嘛,感谢解答~

"cat: /root/.xsession-errors: 没有那个文件或目录"这是为什么呢?

root@peter-PC:/home/peter/Desktop/uos-youqu/wechat_automation_test# youqu manage.py startapp testabc
cat: /root/.xsession-errors: 没有那个文件或目录
cat: /root/.xsession-errors: 没有那个文件或目录
cat: /root/.xsession-errors: 没有那个文件或目录
cat: /root/.xsession-errors: 没有那个文件或目录
No protocol specified
Unable to init server: Could not connect: Connection refused
No protocol specified
Unable to init server: 无法连接:Connection refused
No protocol specified

(manage.py:29977): dbind-WARNING **: 17:19:56.171: Could not open X display

(manage.py:29977): dbind-ERROR **: 17:19:56.177: AT-SPI: Couldn't connect to accessibility bus. Is at-spi-bus-launcher running?
/usr/bin/youqu:行 1: 29977 追踪与中断点陷阱(核心已转储)pipenv run python "$@"

UOS 1070镜像报错:org.freedesktop.DBus.Error.UnknownObject: No such object path '/dde'

self = <apps.autotest_dde_file_manager.case.main_window_area.fixed_directory.trash.test_trash_1062207.TestFileManager object at 0x7f8bc22f28>, open_file_manager = None

    def test_trash_1062207(self, open_file_manager):
        """打开文件管理器--点击菜单--点击设置--对话框下勾选开启普通删除提示"""
        setting = DfmWidget()
        # 点击菜单-设置
        setting.click_setting_in_menu_by_mk()
        # 左键单击对话框侧边栏“对话框”
        setting.click_dialog_box_in_setting_by_attr()
        # 勾选“开启普通删除提示”
        setting.click_general_deletion_tips_in_setting_by_image()
        # 关闭设置窗口
>       setting.click_close_in_setting_by_attr()

case/main_window_area/fixed_directory/trash/test_trash_1062207.py:24: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/home/uos/.local/share/virtualenvs/deepin-autotest-framework-VPJucK3u/lib/python3.7/site-packages/letmego/__init__.py:88: in wrapped
    return func(*args, **kwargs)
/home/uos/.local/share/virtualenvs/deepin-autotest-framework-VPJucK3u/lib/python3.7/site-packages/funnylog/__init__.py:154: in wrapped
    return func(*a, **kw)
widget/pop_widget.py:117: in click_close_in_setting_by_attr
    self.click(*self.ui.btn_center("关闭"))
../../src/button_center.py:445: in btn_center
    btn_x, btn_y = getattr(self, f"btn_center_by_{direction}")(*position)
../../src/button_center.py:300: in btn_center_by_right_top
    window_x, window_y = self.window_right_top_position()
../../src/button_center.py:177: in window_right_top_position
    ) = self.window_location_and_sizes()
../../src/button_center.py:87: in window_location_and_sizes
    app_window_info = self.window_info()
../../src/button_center.py:74: in window_info
    dbus.Interface(proxy_object, "org.kde.KWin").WindowMove()
/home/uos/.local/share/virtualenvs/deepin-autotest-framework-VPJucK3u/lib/python3.7/site-packages/dbus/proxies.py:70: in __call__
    return self._proxy_method(*args, **keywords)
/home/uos/.local/share/virtualenvs/deepin-autotest-framework-VPJucK3u/lib/python3.7/site-packages/dbus/proxies.py:145: in __call__
    **keywords)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dbus._dbus.SessionBus (session) at 0x7f988bf308>, bus_name = dbus.String(':1.25'), object_path = '/dde', dbus_interface = 'org.kde.KWin', method = 'WindowMove', signature = None, args = (), timeout = -1.0
byte_arrays = False, kwargs = {}, get_args_opts = {'byte_arrays': False}, message = <dbus.lowlevel.MethodCallMessage path: /dde, iface: org.kde.KWin, member: WindowMove dest: :1.25>

    def call_blocking(self, bus_name, object_path, dbus_interface, method,
                      signature, args, timeout=-1.0,
                      byte_arrays=False, **kwargs):
        """Call the given method, synchronously.
        :Since: 0.81.0
        """
        if object_path == LOCAL_PATH:
            raise DBusException('Methods may not be called on the reserved '
                                'path %s' % LOCAL_PATH)
        if dbus_interface == LOCAL_IFACE:
            raise DBusException('Methods may not be called on the reserved '
                                'interface %s' % LOCAL_IFACE)
        # no need to validate other args - MethodCallMessage ctor will do
    
        get_args_opts = dict(byte_arrays=byte_arrays)
        if is_py2:
            get_args_opts['utf8_strings'] = kwargs.get('utf8_strings', False)
        elif 'utf8_strings' in kwargs:
            raise TypeError("unexpected keyword argument 'utf8_strings'")
    
        message = MethodCallMessage(destination=bus_name,
                                    path=object_path,
                                    interface=dbus_interface,
                                    method=method)
        # Add the arguments to the function
        try:
            message.append(signature=signature, *args)
        except Exception as e:
            logging.basicConfig()
            _logger.error('Unable to set arguments %r according to '
                          'signature %r: %s: %s',
                          args, signature, e.__class__, e)
            raise
    
        # make a blocking call
        reply_message = self.send_message_with_reply_and_block(
>           message, timeout)
E       dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UnknownObject: No such object path '/dde'

/home/uos/.local/share/virtualenvs/deepin-autotest-framework-VPJucK3u/lib/python3.7/site-packages/dbus/connection.py:651: DBusException

操作校验问题

是否可以给所有键鼠操作附带OCR或者图片循环校验等待功能,默认可以无需校验,我理解大部分一系列UI操作,第一步操作完,界面会产生变化,第二步操作依赖第一步变化后的界面,这个功能可以解决给固定的“操作间隔时间”无法在所有架构系统都合适的问题,毕竟各种机器性能不同。也会缩减开发的代码量。

标签化管理支持判断系统版本跳过用例

/etc/os-version 里面的 MinorVersion 为判断依据,支持判断系统版本跳过用例
image

Tasks

No tasks being tracked yet.

在wayland下执行python3 manage.py -h报错

Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/Xlib/xauth.py", line 43, in init
raw = open(filename, 'rb').read()
FileNotFoundError: [Errno 2] 没有那个文件或目录: ''

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "manage.py", line 574, in
Manage()
File "manage.py", line 144, in init
from src.depends.cfonts import say
File "/tmp/pycharm_project_743/src/init.py", line 21, in
from src.assert_common import AssertCommon as AssertCommon
File "/tmp/pycharm_project_743/src/assert_common.py", line 20, in
from src.dogtail_utils import DogtailUtils
File "/tmp/pycharm_project_743/src/dogtail_utils.py", line 30, in
from src.mouse_key import MouseKey
File "/tmp/pycharm_project_743/src/mouse_key.py", line 35, in
from src.depends.pyautogui import _pyautogui_wayland as pyautogui
File "/tmp/pycharm_project_743/src/depends/pyautogui/init.py", line 250, in
import mouseinfo
File "/usr/local/lib/python3.7/dist-packages/mouseinfo/init.py", line 223, in
_display = Display(os.environ['DISPLAY'])
File "/usr/local/lib/python3.7/dist-packages/Xlib/display.py", line 80, in init
self.display = _BaseDisplay(display)
File "/usr/local/lib/python3.7/dist-packages/Xlib/display.py", line 62, in init
display.Display.init(*(self, ) + args, **keys)
File "/usr/local/lib/python3.7/dist-packages/Xlib/protocol/display.py", line 61, in init
name, host, displayno)
File "/usr/local/lib/python3.7/dist-packages/Xlib/support/connect.py", line 91, in get_auth
return mod.get_auth(sock, dname, host, dno)
File "/usr/local/lib/python3.7/dist-packages/Xlib/support/unix_connect.py", line 103, in new_get_auth
au = xauth.Xauthority()
File "/usr/local/lib/python3.7/dist-packages/Xlib/xauth.py", line 45, in init
raise error.XauthError('~/.Xauthority: %s' % err)
Xlib.error.XauthError: ~/.Xauthority: [Errno 2] 没有那个文件或目录: ''

请问有案例参考吗

首先感谢作者们的出色工作。
我在学习Youqu,但是不知道该如何编写用例,请问能否提供一些case作参考?
(。◕◡◕。)ノ谢谢~

CmdCtl.sudo_run_cmd("xxx")方法没有返回值,期望增加返回值

@classmethod
def sudo_run_cmd(cls, command, interrupt=True, timeout=25, out_debug_flag=True, command_log=True, password=None):
    if password is None:
        password = conf.PASSWORD
    cls.run_cmd(
        f"echo '{password}' | sudo -S {command}",
        interrupt=interrupt,
        timeout=timeout,
        out_debug_flag=out_debug_flag,
        command_log=command_log
    )

CSV跳过用例规则新增

目前csv跳过用例可以按照多种条件进行跳过,但是这些条件不能并列执行,只能跳过单一条件,是否可以支持多个条件并行跳过。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.