支持一下,孔老师好样的!
第 2 点有点没看懂,小号指的是手机号还是微博账号?好像没见过有什么系统登录后会显示不止一个用户的,不知道微博是否有这样的设计。
然后第 3 点,你用微信登录有有绑定回你的手机号吗?正常来说直接微信登录由于拿不到除了微信 id 之外的信息,所以其实没法和你自己手机号绑定的,得人工绑定,且一般要求此时手机号没有绑定过其他账号(按照实名制的要求,一般 1 个手机号只能 1 个账号,确保身份唯一)
第 4 点,爹是谁,娘是谁?
建议除了步骤外,也写上你的预期结果和实际结果吧,这样更清晰,现在通过步骤没看懂你觉得怎样才是对的,所以都不知道具体问题在哪。
看半天没看懂什么 bug,能分步骤 1234 说么?
额,不建议强调 “女” 这个特点,这个帽子太大。我以前团队里女生都很强的,有追求也耐压,干起活来不必男生差甚至更好,所以不要一上来就 “女测试” ,让人有歧视嫌疑。
其实这种问题和男女关系不大,也有遇到过男的类似这样的同学。基本上特点是比较关注工作和生活的平衡,工作之余应该自己也有不少的活动安排,一旦工作加班就会对这些活动产生比较大的影响。倒也没问题,每个人都有自己的追求,只是可能不一定适合自己团队。不妨面试的时候问下对加班的态度如何,可以了解到一些端倪。
不过我觉得,核心点是你招聘时不知道出于什么原因,太倾斜她了,别人都要求的到了她身上就没要求了。这些导致你招了一个其实不那么符合岗位要求的同学进来。感觉她应该会稳定一些
不知道依据是什么?
另外,请不要在面试时产生因为是男生/女生,所以要区别对待的想法。和工作无关的一些人性化的事情可以区别一下(比如加班时尽量男生先上,绅士风度帮忙做一些体力活之类的),但面试考察的是基础能力,这个地方上降低要求的话,后面双方都痛苦。
知道了,踩了暗坑,port forward 模式下转发时,一些和 host 有关的内容没有做替换,只是把内容做了转发。比如 header 里的 host 没改为 proxyRemoteHost 的值。所以背后真实服务看到 host 不大对,就不会正常返回了。
我实际启动命令里的相关配置:
java \
-Dmockserver.initializationJsonPath=${mock_file_path} \
-Dmockserver.watchInitializationJson=true \
-jar mockserver-netty-5.11.1-jar-with-dependencies.jar -serverPort 1080 \
-proxyRemotePort 80 \
-proxyRemoteHost xxx.lizhi.fm
根据日志,转发时使用的 Url 和 header 中 host 字段还是 127.0.0.1:1080 ,不是我配置的 proxyRemote 相关信息。而且通过查服务端日志,会没有相关日志,估计是被框架层处理,都到不了业务逻辑层。
给请求加上 -H 'Host: xxx.lizhi.fm' 后,才能正常返回。详细的后面得再看看源码。
开发场景,客户端和服务端同步开发,客户端前期需要通过 mock 获取所需返回值。
测试场景也偶尔会用到,用于模拟返回特定错误码。
试用了下 port forwarding 的 proxy 方法,配置了 proxyRemotePort 和 proxyRemoteHost 。通过 mock-server 访问返回 404,但直接访问是可以的,看来还要再看看具体源码了。
这个片段看得有点一头雾水,如果是个人笔记可以放在记事本里面?
命中规则返回 mock response, 没有命中规则的话转发给真实服务。
这个是这个 java 应用直接具备的功能,还是通过文中的 go 脚本实现的?看了下 go 脚本,貌似没见到有相关的逻辑。文中的 java mockserver 有提供 proxy 的方式,但也必须要在被测服务里加配置才能实现。
目前实际项目里,需要用到这种指定规则的 mock,非指定的走真实流量。找到的各种 mock 基本都是 mock 整个服务,或者需要到被测系统里加配置,缺少类似网关的实现方式自由选择哪些 mock 哪些直接转发,不大合适。
客气啦。
建议下次遇到这类问题,可以先从开发源码角度看看,开发是怎么做的,再去倒推测试怎么做。现在前端已经发展到基本不怎么需要接触最原生的 html 和 js 的程度了,甚至 css 也基本用框架提供的预置 class,但 selenium 等测试工具为了通用,操作的还是最底层的原生控件。
看到正文更新的源码了,确实是基于双向绑定获取 input 的内容,然后再把 双向绑定的 js 中属性值(在你正文源码里对应的是 formMess.phone ) 放到请求里发给服务端。很常见的 vue 写法,没什么问题。
我也试验了下,vue 的双向绑定应该是基于输入框的一些内容变化的 event 触发的,具体是哪些 event 没深入研究过不大了解。而这些 event 可能没法监听你用 selenium 直接操作 input 输入框 value 这种场景(这种场景用户是做不出来的,只有程序能做出来,所以 vue 不考虑也正常),所以没有触发属性值的更新。
具体试验方式:在 https://vuejs.org/v2/guide/forms.html#Basic-Usage 中,找到 text 的示例,通过 js 直接修改 input 输入框的 value ,输入框的值更新了,但进行双向绑定的 message 没有更新:
一般用 vue 编程,实际发送请求用的是双向绑定后 v-model 里面的属性值,所以有可能这个原因你通过编程直接改变的 input 值,没有同步更新到 v-model 对应属性值里。而你 ctrl+a 再用退格键,基本就和用户操作一样了,所以 event 能捕获到。
贴下开发相关的源码吧?看描述有点一头雾水。如果用的 vue ,把 *.vue 文件的源码贴上来,包括模板部分和 js 部分
得先搞清楚开发怎么实现的输入框提交,才能对应找到最佳的清除方式。vue 这类框架底层自动做了双向数据绑定,输入框的值变化会自动引起某个 js 里面变量的变化,js 变量变化也会自动引起界面绑定元素的变化,所以光看 F12 的编译后代码 html 部分是看不出怎么做的,很多动作是在 js 库中实现的。
PS:如果用了 vue,一般都不会用这个 html 内置的 submit 事件来提交了,因为限制了必须用 form 格式提交,服务端不一定用这个格式解析。结合用 axios 调后端接口更爽呀。
都做 Java 接口级别的测试了,还要专门搞个工具给没有代码能力的同学去测试,感觉是不是有点本末倒置?
不是应该想办法让大家学习掌握些测试所需的写代码能力么?做代码相关的测试,却不掌握代码能力,那不如让开发直接基于 sdk 能力搞个 app(类似各种控件 demo app),让你界面直接调用 sdk 提供的各项功能,做黑盒测试?
怎么获取 authorization 呢
这个,你先了解下开发是怎么获取的?这个东西没有一个标准的方式的,web 常用 cookies 做鉴权,移动端常用 token,甚至还会有别的姿势。这么问我不知道怎么回答你。
这个其实是纯接口测试范畴的问题了,如果你原来就没有接口测试,那从零开始鉴权这块肯定是要首先解决的,初期成本会相对高一点,但突破后只要系统不大改就能继续沿用,属于一次性成本。
如果你们确实本身没有接口测试,现阶段也没打算投入去做,那就先忽略这个点,继续去做纯 UI 自动化呗。个人理解 UI 自动化不应该过度关注实际返回值对不对,只需要关注有返回值、展示正常就可以了。如果非得关注返回值对不对,可以在用例设计上想办法,让每一行的内容相对固定,这样就避免要去问后端,而是可以写死在代码里了。
UI 自动化和人通过 UI 做功能测试还是有差异的,UI 自动化的工具框架基本都是只针对 UI 界面操作,而人去测试 UI 基本都不会只针对 UI 操作,还会结合查数据库、查后台、抓包等动作,多处检查。所以还是我前面说的,不要直接把人测试的用例直接套到 UI 自动化中,成本会比人操作高不少,而且还可能由于涉及系统多,影响稳定性。
这个是现象,我好奇的是本质,为啥打日志会引起线程阻塞。
毕竟对于定位问题,日志是一个很重要的依据,不严重影响性能前提下肯定希望日志越多越好。搞清楚本质才知道应该避免哪些地方打日志导致严重影响性能,预防问题的发生。而且也不是每个需求都有足够的资源和时间去做性能测试的。
原来设计就是这么设计的。
目的主要是让第一页的时候显得内容多,没那么寒酸。
我不是大佬,大佬这个高帽有点大。。。
大家平等交流就好,技术面前无大佬。
客气啦,我也是这么一步一步在别人的帮助下走过来的。
也期望以后多来社区走走,遇到其他人有问题也可以协助解答下,让大家都能在这里有所成长吧。
1.用例存在空搜索,即搜索内容为空时,点击搜索,这个情况出来的是全部的,需要一个一个比对,因为之前出过每次点击一个新页面都重新排序的 bug
抽样也能发现这个问题,比如固定抽取 1、3、5 三个样本,排序类问题是可以发现的。也建议你了解下,之前这个 bug 是服务端问题还是客户端问题,如果是服务端问题,那通过接口测试预防成本更低。测试应该用最低成本发现最多问题,做自动化更要留意这个点,因为自动化不同方法之间成本会差别挺大的
如果全放到用例中,两个列表对比,肯定是要 for 循环,放到用例中感觉又不太合适
好奇问下,为啥觉得不太合适?个人觉得倒是最合适的地方了,因为用例需要做检查点校验。至于 for 循环,你做抽样的话就不用循环了,固定写死 2-3 个位置就好。
请问还需要封装 element.find_element 方法和 get_element_text_by_element 方法吗
能否详细说明下你想封装这两个方法的原因,以及模拟下封装和不封装在用例实际写法上的区别?这个要看实际使用场景的,没有绝对的答案。按现在的信息不是太充分,不好给你意见。
这个是不是有点简略过头了?
好奇为啥打日志会引起阻塞?因为 IO 输出已经满了?
写得挺完整的,点个赞。
期望后面能分享下实际项目中的实战情况,文中的 “实战” 我理解只是跑通一个 demo,和项目实战还是有点差距的。
整理挺用心的,点个赞。
不过这里看起来都是数据操作层面的优化策略,是不是还缺少了比如计算速度或者算法优化方面的优化策略?
看到标题进来后,感觉这个白盒和我理解有点出入。我理解这个只是灰盒,不至于纯黑盒只看到界面,但也没像白盒那样深入代码校验分支覆盖。
我觉得你这个方向还是不错的,通过反射让方法名和参数都变成配置文件可以自由配置的项,这样可以不写代码,只改配置来完成测试用例,写起来应该比较快。缺点是没有 idea 自动提示,有可能会写错而不自知;另一个缺点是不好选择性执行,可能要通过手动注释的方法来做。
其实一般这类接口都不会轻易改的,可以考虑类似单测那样,直接就老老实实一个一个函数调用写上去,有 idea 自动补全还不容易写错。如果要做参数化可以结合数组之类的做,可以参考 groovy 的 spock 测试框架,或者 testng 的 parameters 来做入参配置化。好处和缺点和你的 json 方案刚好反过来。你可以按自己需要选择。
另外,异常场景要考虑抛异常这类场景,毕竟是 java 接口,抛 exception 还是很正常的,但我看你好像没提到。
通过 selenium 验证某个搜索功能时,需要验证每一行是否正确,领导建议从数据库里面取然后验证
这个出发点有点不对吧,如果搜索功能不是用 sql 实现,而是大数据通过推荐算法来做就 gg 了,压根没 sql 给你查。。。
如果你是纯验证 ui ,可以对比相同参数请求接口的返回值是否正确,基本上选 2-3 个抽样检查就好了。
如果你是要 ui 和服务端功能都验证,那建议你还是拆开两端来测试吧。
PS:搜索功能绝大部分逻辑在服务端,本身更适合接口测试。客户端的 UI 自动化去验证这个有点本末倒置了,效率也不高。UI 自动化!=手工检查的点都变成自动化检查 ,最典型的例子就是排版问题。手工一眼能看出的排版问题,对 UI 自动化却是个技术难题(当然现在也有公司已经突破了,可以自动识别排版异常),这种情况就不大适合用 UI 自动化去做。
跑了一下代码,找到原因了,本质还是你语法写错了。
// 网上找的示例
WebDriverWait(self.driver, 900).until(
EC.text_to_be_present_in_element(
(By.ID, 'operations_monitoring_tab_current_ct_fields_no_data'),
"No data to display"
)
)
// 你帖子正文给的写法,搜了下应该是你从 csdn 之类复制过来的,这段写法是没错的
WebDriverWait(driver, 10).until(
expected_conditions.text_to_be_present_in_element(
(By.CSS_SELECTOR,"#TANGRAM__PSP_10_error"),
u'请您填写手机/邮箱/用户名'
)
)
// 你评论给的写法,你可以对比下 text_to_be_present_in_element 第一个参数的数据类型,是不是 tuple
WebDriverWait(self.driver, 10).until(
EC.text_to_be_present_in_element(
By.CSS_SELECTOR,
'#map > div.main-wrapper > div > div > div.stic'
'ker > div > div > div.ivu-table-wrapper > div > di'
'v.ivu-table-body > table > tbody > tr > td:nth-child(3) > div > span'
),
u'hahaha'
)
至于为啥报错是 13 个参数,原因是这样的:
1、text_to_be_present_in_element 接收的第一个参数,最后会以 *by 的形式传给底层的 find_element 函数。所以应该是一个带有 2 个元素的 tuple 。
2、由于上面括号用的不对,所以实际第一个参数的值是 By.CSS_SELECTOR,即字符串 'css selector' (你可以自行在 idea 里跳到这个常量的定义里看看)
3、find_element 函数定义是 find_element(self, by=By.ID, value=None)
,本身默认有个 self 参数,再加上 css selector 12 个字符串(当通过 *变量名
传入时,字符串会被解析成一个字母一个元素的数组,等价于 find_element(self, 'c', 's', 's', ' ', 's', 'e','l','e','c','t','o','r')
),所以就变成了 13 个参数了。
举证:
by = '123'
self.driver.find_element(*by)
// 跑上面这两行代码,会报错:
// TypeError: find_element() takes from 1 to 3 positional arguments but 4 were given
建议下次出问题,还是和上面一样,把你实际代码和完整堆栈贴上来吧。要不从你那个网上找到的代码,真的没办法找到原因,因为这段代码本身就没错。