• 课间作业:

  • 作业1:

    def test_xueqiu_hamcrest(self):
    url="https://101.201.175.228/v5/stock/portfolio/stock/list.json"
    cookies = {"xq_a_token": "5806a70c6bc5d5fb2b00978aeb1895532fffe502", "u": "3446260779"}
    params = {"t": "1UNKNOWNc60715cb4a61425b311034a49f4aa024.3446260779.1563002521424.1563005246620",
    "_s": "8c6b2d",
    "category": "1"
    }
    headers = {"User-Agent": "Xueqiu Android 11.19", "Accept-Language": "en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4",
    "Host": "stock.xueqiu.com"}
    r = requests.get(url=url,
    params=params,
    cookies=cookies,
    headers=headers,
    verify=False
    )
    logging.info(jsonpath.jsonpath(r.json(), "$.data.stocks[*].name"))
    assert_that(jsonpath.jsonpath(r.json(),"$.data.stocks[*].name"),any_of(has_item("招商银行"),has_item("平安银行")))
  • 作业1:
    实现个人上市,股价9999.99,或者更高,把修改成功的截图贴到帖子里。本质上这是一个常用的测试场景,修改接口的返回,去测试app端的展示逻辑

    作业2

    class Test_requests(object):
    url = 'https://stock.xueqiu.com/v5/stock/portfolio/stock/list.json'
    logging.basicConfig(level=logging.INFO)
    def test_xueqiu_quote(self):
    cookies = {'xq_a_token':'5806a70c6bc5d5fb2b00978aeb1895532fffe502',
    'u':'3446260779'}
    header={'Accept-Language': 'en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4',
    'User-Agent': 'Xueqiu Android 11.19'}
    params ={'category':'1'}
    r = requests.get(self.url,params=params,headers=header,cookies=cookies)
    logging.info(json.dumps(r.json(),indent=2))
  • 作业1:

    curl -v www.baidu.com -H 'test:harry@Hogwarts' -v

    作业2:

  • import time
    from selenium import webdriver

    class Testxueqiu(object):
    def test_xueqiu(self):
    driver = webdriver.Chrome() //如果报driver错误的时候,注意chrome一定要首字母大写
    driver.get("http://xueqiu.com") //打开浏览器
    driver.implicitly_wait(30)
    driver.find_element_by_xpath('.//*[@placeholder="搜索"]').send_keys("alibaba")
    driver.find_element_by_css_selector('.Header_nav__search__addon_2nk').click()
    driver.find_element_by_xpath('//*[text()="BABA"]/../../../..//*[@class="follow__control"]').click()
    driver.find_element_by_name("username").send_keys("13800138000")
    time.sleep(2)
    driver.find_element_by_name("password").send_keys("123456")
    time.sleep(2)
    driver.find_element_by_css_selector('.modal__login__btn').click()
    driver.quit()
  • 作业1:点击雪球行情,获得“深证成指”的指数,判断是否大于8000点
    添加一个HQingPage.py

    from appium.webdriver.common.mobileby import MobileBy
    from xueqiu.page.BasePage import *

    class HQingPage(BasePage):
    def getHQing(self,name)-> float:
    pricelocator=(MobileBy.XPATH,"//*[contains(@resource-id,'index_name')and @text='%s']"%name +"/..//*[contains(@resource-id, 'index_price')]")
    price=self.find(pricelocator).text
    self.driver.implicitly_wait(10)
    return float(price)

    MainPage.py里添加一个函数

    def gotoHQing(self):
    AndroidClient.driver.find_element_by_xpath("//*[@text='行情']")
    AndroidClient.driver.find_element_by_xpath("//*[@text='行情']").click()
    return HQingPage()

    添加一个testcase_hq用例

    from xueqiu.page.MainPage import *

    class TestHQIndex(object):
    # 获取深证成指的指数,判断是否大于8000
    def test_sc(self):
    main=MainPage()
    price= main.gotoHQing().getHQing("深证成指")
    print(price)
    assert price >8000
  • 基金开户 蛋卷已有账户登录 密码登陆 输入错误的用户名和密码,点击安全登陆

    #! /usr/bin/env python
    #coding=utf-8


    from appium import webdriver
    import pytest
    from appium.webdriver.common.mobileby import MobileBy
    from appium.webdriver.webdriver import WebDriver
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC

    class TestDanjuan:
    driver = WebDriver
    phone = (MobileBy.ID, "telno")#登录页面的手机号输入框
    password = (MobileBy.ID, "pass")#密码输入框
    login =(MobileBy.ID,"next")# 安全登录按钮
    button = (MobileBy.ID, "button1") # 错误提示框-确定按钮

    def restart_app(cls):
    caps = {}
    caps["platformName"] = "android"
    caps["deviceName"] = "hogwarts"
    caps["appPackage"] = "com.xueqiu.android"
    caps["appActivity"] = ".view.WelcomeActivityAlias"
    caps['autoGrantPermission'] = 'true'
    caps['unicodeKeyboard'] = 'true'
    caps['resetKeyboard'] = 'true'
    caps['noReset'] = 'true' # 保留之前数据
    driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
    driver.implicitly_wait(40)
    return driver

    def setup_method(self):
    print("每次启动前都执行")
    self.driver = self.restart_app()
    WebDriverWait(self.driver, 30).until(EC.presence_of_element_located((MobileBy.XPATH, "//*[@text='交易']")))
    self.driver.find_element_by_xpath("//*[@text='交易']").click()#点击进入交易页面
    WebDriverWait(self.driver, 30).until(EC.presence_of_element_located((MobileBy.ACCESSIBILITY_ID, "基金开户")))
    self.driver.find_element_by_accessibility_id('基金开户').click()
    WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((MobileBy.ACCESSIBILITY_ID, "已有蛋卷基金账户登录")))
    self.driver.find_element_by_accessibility_id('已有蛋卷基金账户登录').click()

    @pytest.mark.parametrize("phone,password",
    [("13900130100", "123456")])
    def test_login_pwd(self,phone,password):
    WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((MobileBy.ACCESSIBILITY_ID, "安全登录")))
    self.driver.find_element_by_accessibility_id('使用密码登录').click()
    WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((MobileBy.ACCESSIBILITY_ID, "登录密码")))
    self.driver.find_element(*self.phone).send_keys(phone)
    self.driver.find_element(*self.password).send_keys(password)
    self.driver.find_element(*self.login).click()
    msgerror = self.driver.find_element_by_id('message').get_attribute('name')
    assert '你输入的手机号码或者密码有误' in msgerror
    self.driver.find_element(*self.button).click()
  • 作业1
    找出如下按钮的定位符,回复到帖子下

    //*[@text='基金' and @instance='9']
    //*[@resource-id='com.xueqiu.android:id/indicator']//*[@text='基金']
    //*[contains(@resource-id, 'indicator')]//*[@text='基金']

    作业2
    进入雪球首页,进入基金的新闻页(不是第一个基金按钮),对他以及它右侧的每个新闻栏目,执行上滑5次,进入下个栏目用从右边到左边滑动
    滑动使用相对坐标,而不是绝对坐标

    import time
    import pytest
    from appium import webdriver
    from appium.webdriver.common.touch_action import TouchAction

    class TestXueQiu(object):

    @classmethod
    def setup_class(cls):
    caps = {}
    caps["platformName"] = "android"
    caps["deviceName"] = "hogwarts"
    caps["appPackage"] = "com.xueqiu.android"
    caps["appActivity"] = ".view.WelcomeActivityAlias"
    caps["autoGrantPermissions"] = "True"
    driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
    driver.implicitly_wait(10)
    driver.quit()
    print('setup_class是在类开始时,只执行一次')

    def setup_method(self):
    caps = {}
    caps["platformName"] = "android"
    caps["deviceName"] = "hogwarts"
    caps["appPackage"] = "com.xueqiu.android"
    caps["appActivity"] = ".view.WelcomeActivityAlias"
    caps['noReset'] = "True"
    caps["automationName"] = "uiautomator2"
    self.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
    self.driver.implicitly_wait(10)
    print('setup_method是在类方法前执行一次')

    def teardown_method(self):
    self.driver.quit()

    def test_news(self):
    # 找到基金一栏,父节点的resource-id='indicator'
    ele1 = self.driver.find_element_by_xpath("//*[contains(@resource-id, 'indicator')]//*[@text='基金']")
    ele1.click()
    time.sleep(3)
    action1 = TouchAction(self.driver)
    size1 = self.driver.get_window_size()#获取屏幕的宽和高

    for i in range(7):#页面向左滑动
    for j in range(5):#页面向下滑动
    action1.press(x=size1['width']*0.7,y = size1['height']*0.7).move_to(x=size1['width']*0.7,y = size1['height']*0.3).release().perform()
    time.sleep(4)
    action1.press(x=size1['width']*0.8,y = size1['height']*0.5).move_to(x=size1['width']*0.1,y = size1['height']*0.5).release().perform()
    time.sleep(4)

    if __name__ == "__main__":
    pytest.main(["-s","test_002.py","./report/test_news"])

    作业3
    完成雪球登录场景的测试
    要去带有setup_class setup_method体系
    微信 验证码 密码 错误的用户名 错误的密码 至少编写5条用例
    作业上传到github,如果不会上传github,直接贴到回复里整个文件代码也可以。

    #! /usr/bin/env python
    #encoding=utf-8
    #coding=utf-8

    import time
    import pytest
    from appium import webdriver
    from appium.webdriver.common.touch_action import TouchAction
    from nose.plugins.builtin import cls
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.wait import WebDriverWait


    class TestXueqiu():
    icon1 = (By.ID,"user_profile_icon")#首页的按钮,进入‘我的’页面
    tv_login = (By.ID, "tv_login") # ‘我的’页面,登录按钮

    # 微信登录
    weixin_login = (By.XPATH, "//*[@text='微信登录']") # 选择微信
    webchat_num_id = (By.XPATH, "//*[@text='请填写微信号/QQ号/邮箱']") # 微信账号
    webchat_password_id = (By.XPATH, "//*[@text='请填写密码']") # 密码
    weixin_action_login = (By.XPATH, "//*[@text='登录']") # 微信登录按钮
    error = (By.ID, "cvr") #跳出错误弹框
    error_icon = (By.XPATH, "//*[@text='确定']") #关闭弹框
    weixin_action_back = (By.XPATH, "//*[@content-desc='返回'']") # 微信登录界面-退回
    iv_close = (By.ID, "iv_close") # 登录页-关闭按钮,回到‘我的’

    phone_or_others = (By.ID, "tv_login_by_phone_or_others") # 手机及其他登录
    # 手机及其他登录
    account_login = (By.ID, "register_phone_number") # 请输入手机号
    register_code_text = (By.ID, "register_code_text") # 发送验证码
    register_code = (By.ID, "register_code") # 请输入四位验证码
    button_next = (By.ID, "button_next") # 登录按钮
    iv_action_back = (By.ID, "iv_action_back") # 手机号登录页面-退回

    # 邮箱手机号密码登录
    tv_login_with_account = (By.ID, "tv_login_with_account") # 邮箱手机号密码登录
    login_account = (By.ID, "login_account") # 请输入手机号或邮箱
    login_password = (By.ID, "login_password") # 请输入登录密码

    # 验证码错误 用户名或密码错误 重复次数过多,请重试获取
    content = (By.ID, "content") # 错误提示框
    md_buttonDefaultPositive = (By.ID, "md_buttonDefaultPositive") # 确定按钮,点击则关闭

    @classmethod
    def install_app(cls):
    caps = {}
    caps["platformName"] = "android"
    caps["deviceName"] = "hogwarts"
    caps["appPackage"] = "com.xueqiu.android"
    caps["appActivity"] = ".view.WelcomeActivityAlias"
    caps['autoGrantPermission'] = 'true'
    driver = webdriver.Remote("http://localhost:4723/wd/hub",caps)
    driver.implicitly_wait(50)
    driver.quit()
    return driver

    @classmethod
    def restart_app(cls):
    caps = {}
    caps["platformName"] = "android"
    caps["deviceName"] = "hogwarts"
    caps["appPackage"] = "com.xueqiu.android"
    caps["appActivity"] = ".view.WelcomeActivityAlias"
    caps['autoGrantPermission'] = 'true'
    caps['unicodeKeyboard'] = 'true'
    caps['resetKeyboard'] = 'true'
    caps['noReset'] = 'true'#保留之前数据
    driver = webdriver.Remote("http://localhost:4723/wd/hub",caps)
    driver.implicitly_wait(50)
    return driver

    def setup_class(self):
    print("安装程序后第一次启动")
    self.driver = self.install_app()
    WebDriverWait(self.driver, 30)


    def setup_method(self):
    print("每次启动前都执行")
    self.driver = self.restart_app()
    WebDriverWait(self.driver, 30)
    self.driver.find_element(*self.icon1).click() #点击首页按钮
    self.driver.find_element(*self.tv_login).click() #进入登录页面

    #登录页面-微信登录
    @pytest.mark.parametrize("phone,password",
    [("138001380000", "123456")])
    def test_weixin_error(self, phone,password):
    self.driver.find_element(*self.weixin_login).click()
    self.driver.implicitly_wait(5)
    #输入账号和密码
    self.driver.find_element(*self.webchat_num_id).send_keys(phone)
    self.driver.implicitly_wait(5)
    self.driver.find_element(*self.webchat_password_id).send_keys(password)
    self.driver.implicitly_wait(5)
    self.driver.find_element(*self.weixin_action_login).click()
    self.driver.implicitly_wait(5)
    #关闭错误提示,退出登录页面
    self.driver.find_element(*self.error_icon).click()
    self.driver.implicitly_wait(5)
    self.driver.find_element(*self.weixin_action_back).click()
    self.driver.implicitly_wait(5)
    self.driver.find_element(*self.iv_close).click()

    # 手机登录
    def test_phone_or_others(self):
    self.driver.find_element(*self.phone_or_others).click()
    # 手机账号 验证码
    self.driver.find_element(*self.account_login).send_keys("13800138000")
    self.driver.find_element(*self.register_code_text).click()
    self.driver.implicitly_wait(3)
    #要如何获取验证码没有想好,先造一个输入
    self.driver.find_element(*self.register_code).send_keys("1234")
    # 登录
    self.driver.find_element(*self.button_next).click()
    self.driver.implicitly_wait(3)
    # 弹窗 验证码错误
    error1 = self.driver.find_element(*self.content).text
    if error1:
    # 关闭提示框
    self.driver.find_element(*self.md_buttonDefaultPositive).click()
    # 登录
    self.driver.find_element(*self.phone_action_back).click()

    # 错误的账号密码登录
    @pytest.mark.parametrize("phone,password",
    [("123445555@qq.com", "123456")])
    def test_error(self, phone, password):
    self.driver.find_element(*self.phone_or_others).click()
    self.driver.implicitly_wait(5)
    self.driver.find_element(*self.tv_login_with_account).click()
    self.driver.implicitly_wait(5)
    self.driver.find_element(*self.login_account).click()
    self.driver.implicitly_wait(5)
    # 输入账号密码
    self.driver.find_element(*self.login_account).send_keys(phone)
    self.driver.implicitly_wait(5)
    self.driver.find_element(*self.login_password).send_keys(password)
    self.driver.implicitly_wait(5)
    # 登录
    self.driver.find_element(*self.button_next).click()
    self.driver.implicitly_wait(3)
    # 弹窗 用户名或密码错误
    error2 = self.driver.find_element(*self.content)
    if error2:
    # 关闭提示框
    self.driver.find_element(*self.md_buttonDefaultPositive).click()
    self.driver.implicitly_wait(3)
    # 关闭返回
    self.driver.find_element(*self.iv_action_back).click()

    def teardown_method(self):
    print("teardown_method")

  • unittest作业
    1、写个简单的计算器功能,大小写转换功能,随机生成字符串功能
    test0509.py

    #! /usr/bin/env python
    #encoding=utf-8

    import random
    import string

    def calculator(a,sym,b):
    if sym == '+':
    return a+b
    elif sym =='-':
    return a-b
    elif sym == '*':
    return a*b
    elif sym == '/':
    if b==0:
    return '除数不能为0'
    else:
    return a/b
    else:
    return "不支持该运算符"

    def change(string,type):

    if type =='大写':
    return string.upper()
    elif type =='小写':
    return string.lower()
    else:
    return "不支持该种类型转换"

    def gen_str (num):
    # 从a-zA-Z0-9生成指定数量的随机字符
    ran_str = ''.join(random.sample(string.ascii_letters + string.digits, num))
    return ran_str


    if __name__ == '__main__':
    num1=int(input("请输入第1个数字:"))
    num2=int(input("请输入第2个数字:"))
    sym1=input("请输入运算符:")
    print (calculator(num1,sym1,num2))
    str1=input("请输入字符串:")
    type1=input("请输入字符串要转变的类型:")
    print (change(str1,type1))
    n1 = int(input('请输入要生成的字符串长度:'))
    print(gen_str(n1))

    2、编写测试用例,不同的数据(你能想到的所有测试用例),并进行断言。除0的选择可以跳过skip,随机生成字符串功能可以断言是否包含你名字的缩写。
    testcase0509.py

    import unittest
    from test0509 import *
    from parameterized import parameterized

    class TestCal(unittest.TestCase):
    @parameterized.expand([
    ("加法",5,'+',5,10),
    ("减法",5,'-',5,0),
    ("乘法",5,'*',5,25),
    ("除法",5,'/',5,1),
    ])
    def test_cal_0(self,name,a,b,c,d):
    cal =calculator(a,b,c)
    self.assertEqual(cal,d)
    @unittest.skip('除数为0的,跳过')
    def test_cal_1(self):
    cal=calculator(5,'/',0)
    self.assertEqual(result,'除数不能为0')

    class TestChange(unittest.TestCase):
    @parameterized.expand([
    ("大写",'abcder','大写','ABCDER'),
    ("小写",'OPQR','小写','opqr'),
    ("错误类型",'kydd','abc','不支持该种类型转换')

    ])
    def test_change_0(self,name,a,b,c):
    ch1 =change(a,b)
    self.assertEqual(ch1,c)

    class Test_genstr(unittest.TestCase):
    @parameterized.expand([
    ("自动生成",25,'harry'),
    ])
    def test_genstr(self,name,a,b):
    gen1=gen_str(a)
    self.assertIn(b,gen1)

    if __name__ == '__main__':
    unittest.main(verbosity=2)

    使用unittest框架+HTMLTestRunner,最后生成html报告

  • 作业1
    设计一个表示服务器的类。包含服务器的属性有:CPU个数,内存大小,磁盘空间大小, 操作系统类型(Linux, Windows), 其中操作系统类型设置为私有变量,外部不可以更改。 实现一个方法,输出服务器的属性内容为以下格式:8核CPU, 40G内存,150G磁盘空间,Linux

    class Server:
    def __init__(self,cpu,mem,disk,os):
    self.cpu=cpu
    self.memory=mem
    self.disk=disk
    self.__system=os
    def get_os(self):
    return self.__system
    def get_detail(self):
    print("%s核CPU,%sG内存,%sG磁盘空间,操作系统:%s" % (self.cpu, self.memory, self.disk, self.get_os()))

    if __name__=='__main__':
    Server1=Server(8,40,150,'LINUX')
    Server1.get_detail()

    作业2
    设计一个作业1中服务器的子类,实现一个新的方法,根据 cpu个数,内存大小,磁盘空间大小计算出服务器当前价格# 在子类里面实现一个服务价格的函数。# 计算公式为: CPU 个数* 1527.679+ 内存大小G * 100.21+ 磁盘空间大小G * 50.789 。 返回数据类型为浮点型。保留小 数点后2位 。 并实例化此方法,打印出价格。# Round实现小数点后2位

    class Serverprice(Server):
    def __init__(self,cpu,mem,disk,os):
    Server.__init__(self,cpu,mem,disk,os)
    def get_price(self):
    price = round(self.cpu * 1527.679 + self.memory * 100.21 + self.disk * 50.789, 2)
    return "服务器价格=%.2f" % price

    if __name__=='__main__':
    Serverp1=Serverprice(8,40,150,'LINUX')
    print (Serverp1.get_price())

    作业3:对下面测试方法使用pytest的rerun, 参数化方法来实现自动化测试
    #! /usr/bin/env python
    #coding=utf-8
    import random

    def bubble_sort(nums):
    for i in range(len(nums)-1):
    for j in range(len(nums)-i-1):
    if nums[j] > nums[j+1]:
    nums[j], nums[j+1] = nums[j+1], nums[j]
    return random.choice([nums,None,10])

    import random
    import pytest

    def bubble_sort(nums):
    for i in range(len(nums)-1):
    for j in range(len(nums)-i-1):
    if nums[j] > nums[j+1]:
    nums[j], nums[j+1] = nums[j+1], nums[j]
    return nums

    @pytest.mark.flaky(reruns=5,reruns_delay=1)#重跑5次,重跑时等待1s再执行
    #不加mark命令行中:pytest zuoye/test_rerun.py --reruns 5 --reruns-delay 1
    def test_sort():
    list = [random.randint(1, 100) for i in range(10)]
    print(list)
    list_sort=bubble_sort(list)
    print(list_sort)
    list_sort_new=bubble_sort(list)
    print(list_sort_new)
    assert list_sort !=list_sort_new

    #因为上述结果执行始终正确,所以可以通过修改assert list_sort !=list_sort_new,让结果一直失败,来查看是否rerun功能是否实现