二刷Java官方教程
第二次阅读Java官方教程,有些不一样的理解。内容比较散乱,个人意识流笔记。
第二次阅读Java官方教程,有些不一样的理解。内容比较散乱,个人意识流笔记。
本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 回顾 tep是基于pytest开发的接口测试框架,上个版本从小工具升级为了关键字驱动框架,通过pystats发现最近半年仍然有4000+人次在安装使用tep。时隔1年后,我对tep进行了一次大版本改造,抛弃tep2的Java代码风格,重新回归到tep1的纯粹Python风格。 纯粹Python 所谓纯粹Python,体现在两个方面,一个方面是tep源码进行了重写,更加Pythonic,自动化用例写起来也更加简单易懂;另一方面是抛弃了依赖Java的Allure和依赖C++的loguru,分别使用Python技术栈的pytest-html和logging替代。 tep3版本 简介 tep是Try Easy Pytest的首字母缩写,帮你轻松上手pytest。 框架特点: 基于pytest封装,成熟、稳定且扩展性强。 框架完全由Python构建,没有混杂其他语言。 原生Python语法,学习Python,零成本使用框架。 HAR包转换pytest用例。 安装 支持Python3.8以上版本 创建虚拟环境:python -m venv venv 激活虚拟环境,Windows用户:activate.bat Mac用户:source venv/bin/activate 安装tep:pip install tep 验证安装成功:tep -V 目录结构 data file fixture report scripts tests .gitignore conftest.py pytest.ini run.py tep new demo就能快速创建项目名称为demo的项目脚手架。 用例示范 简单的请求: from tep import request def test(): response = request("get", url="http://httpbin.org/status/200") assert response.status_code == 200 复杂的场景: from tep import request from tep import v from data.global_data import GlobalData class Data: v({ "domain": GlobalData.domain, "skuNum": 2, "payAmount": 0.2 }) body_add_cart = '{"skuId":"${skuId}","skuNum":${skuNum}}' body_order = '{"skuId":"${skuId}","price":${skuPrice},"skuNum":${skuNum},"totalPrice":${totalPrice}}' body_pay = '{"orderId":"${orderId}","payAmount":${payAmount}}' def test(): url = v("${domain}/searchSku?skuName=book") response = request("get", url=url, headers=GlobalData.headers) assert response.status_code < 400 v("skuId", response.jsonpath("$.skuId")[0]) v("skuPrice", response.jsonpath("$.price")[0]) url = v("${domain}/addCart") body = v(Data.body_add_cart) response = request("post", url=url, headers=GlobalData.headers, json=body) assert response.status_code < 400 v("skuNum", response.jsonpath("$.skuNum")[0]) v("totalPrice", response.jsonpath("$.totalPrice")[0]) url = v("${domain}/order") body = v(Data.body_order) response = request("post", url=url, headers=GlobalData.headers, json=body) assert response.status_code < 400 v("orderId", response.jsonpath("$.orderId")[0]) url = v("${domain}/pay") body = v(Data.body_pay) response = request("post", url=url, headers=GlobalData.headers, json=body) assert response.status_code < 400 assert response.jsonpath("$.success")[0] == "true" 用例和数据 数据怎么存放,这里给出了一个参考方案,在用例内定义class Data,然后通过类变量存放数据。不同的项目,不同的场景,不同的参数,可以考虑不一样的存放方式。 ...
系统架构是软件系统的结构化解决方案,它定义了:系统组件及其相互关系,组件与环境的关系,指导设计和演进的原则,技术标准和约束条件,质量属性实现方案,系统各层面的抽象描述,关键设计决策文档,系统演进路线图。
如果你想自我提升却找不到合适方法,或者学习没有什么效果,希望这篇文章能给你带来些许启发。
本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Processing Data in Memory The Stream API is probably the second most important feature added to Java SE 8, after the lambda expressions. In a nutshell, the Stream API is about providing an implementation of the well known map-filter-reduce algorithm to the JDK. map-filter-reduce: List<Sale> sales = ...; // this is the list of all the sales int amountSoldInMarch = 0; for (Sale sale: sales) { if (sale.getDate().getMonth() == Month.MARCH) { amountSoldInMarch += sale.getAmount(); } } System.out.println("Amount sold in March: " + amountSoldInMarch); map:通过get取值,将部分字段映射到新数据(select字段) ...
本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 locustfile是什么? locustfile是Locust性能测试工具的用户脚本,描述了单个用户的行为。 locustfile是个普通的Python模块,如果写作locustfile.py,那么路径切换到文件所在目录,直接执行命令就能运行: $ locust 如果换个名字,那么只能通过-f参数指定文件名运行: $ locust -f locust_files/my_locust_file.py 与一般Python模块不同的是:locustfile必须至少定义一个类,且继承自User类。 User类 User类表示性能测试的模拟用户,Locust会在运行时创建User类的实例。 wait_time属性 设置等待时间,默认值不等待,立即执行。 Locust支持4种方式设置wait_time属性。 为了便于理解实际意义,我把源码贴在了下面。 constant函数,常量,任务执行完毕等待X秒开始下一任务。 def constant(wait_time): """ Returns a function that just returns the number specified by the wait_time argument Example:: class MyUser(User): wait_time = constant(3) """ return lambda instance: wait_time between函数,区间随机值,任务执行完毕等待X-Y秒(中间随机取值)开始下一任务。 def between(min_wait, max_wait): """ Returns a function that will return a random number between min_wait and max_wait. Example:: class MyUser(User): # wait between 3.0 and 10.5 seconds after each task wait_time = between(3.0, 10.5) """ return lambda instance: min_wait + random.random() * (max_wait - min_wait) constant_pacing函数,自适应,若任务耗时超过该时间,则任务结束后立即执行下一任务;若任务耗时不超过该时间,则等待达到该时间后执行下一任务。 def constant_pacing(wait_time): """ Returns a function that will track the run time of the tasks, and for each time it's called it will return a wait time that will try to make the total time between task execution equal to the time specified by the wait_time argument. In the following example the task will always be executed once every second, no matter the task execution time:: class MyUser(User): wait_time = constant_pacing(1) @task def my_task(self): time.sleep(random.random()) If a task execution exceeds the specified wait_time, the wait will be 0 before starting the next task. """ def wait_time_func(self): if not hasattr(self, "_cp_last_run"): self._cp_last_wait_time = wait_time self._cp_last_run = time() return wait_time else: run_time = time() - self._cp_last_run - self._cp_last_wait_time self._cp_last_wait_time = max(0, wait_time - run_time) self._cp_last_run = time() return self._cp_last_wait_time return wait_time_func 自定义wait_time方法,比如每次等待时间1秒2秒3秒递增: class MyUser(User): last_wait_time = 0 def wait_time(self): self.last_wait_time += 1 return self.last_wait_time ... ...
本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 四种参数 Python函数func定义如下: def func(first, *args, second="Hello World", **kwargs): print(first) print(args) print(second) print(kwargs) func("dongfanger", "san", py="good") 运行后会输出: dongfanger ('san',) Hello World {'py': 'good'} 它有四种参数: first是定位参数,positional parameter,不可省略。 *args是可变参数,arguments,存入元组。 second是默认值参数,default argument values,可以省略。 **args是关键字参数,keyword arguments,存入字典。 func函数的调用方式有以下这些: ①传入单个定位参数。 func("dongfanger") dongfanger () Hello World {} ②第一个参数后的任意个参数会被*args捕获,存入一个元组。 func("dongfanger", "a", "b", "c") dongfanger ('a', 'b', 'c') Hello World {} ③没有明确指定名称的关键字参数会被**kwargs捕获,存入一个字典。 func("dongfanger", j="1", k="2") dongfanger () Hello World {'j': '1', 'k': '2'} ④second只能作为关键字参数传入。 func("dongfanger", second="cool") dongfanger () cool {} ⑤定位函数也能作为关键字参数传入。 func(first="san") san () Hello World {} ⑥字典前加上**,其所有元素作为单个参数传入,同名键会绑定到对应具名参数上,余下的被**args捕获。 ...
正式版教程: https://dongfanger.gitee.io/blog/tep.html
本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Storing Data The Collections Framework is the most widely used API of the JDK. 集合不是数据类型,它是JDK的API,可以用来存储数据等,相当于数据结构。 the Collections Framework is a set of interfaces that models different way of storing data in different types of containers. Then the Framework provides at least one implementation for each interface. There are two main categories of interfaces in the Collections Framework: collections and maps.(所以我猜想Python也是基于这样的考虑,设计了List和Dict,并作为Python基本数据类型,实际编码中要用到的也主要是这两类) That makes two main categories, Collection and Map, a subcategory, Queue, and a side category, Iterator. ...
Locust是一款Python技术栈的开源的性能测试工具。Locust直译为蝗虫,寓意着它能产生蝗虫般成千上万的并发用户: