CuriousY A world with wonder

前端测试初窥

| Comment

前端测试测什么###

Unit testing。具体到现在组件化的前端代码中就是对每个组件(中的每个函数)来进行单独的测试,这些测试包括组件的渲染结果、组件的事件处理、乃至某个函数被调用的次数等。

在看Jest官方文档的时候看到一种测试方法(它称之为snapshot testing),每次测试它会把一些React组件渲染得到的DOM tree保存下来,并和之前得到的结果做比较,如果结果没有变化则算是通过测试(这里以该组件没有什么改动为前提)。

还有一种测试和snapshot testing有一些像,叫做visual regression testing,该测试每次会把渲染好的页面截图保存为图片,再和之前保存的结果图片进行像素级别的比较。

End-to-end testing,这种测试也很好理解,即利用脚本在渲染好的页面上来模拟人为的一系列页面操作,通过操作结果来判断页面的功能是否正常运作(因为是在“实地”操作,所以找到的bug也可能是后端的)。通常,在每个步骤中也会进行页面的截图来进行visual regression testing。(对于这类测试,其实可以通过monitor页面的操作变化(手动操作)来自动生成操作的脚本,这样我们就只需要写assertion就可以啦)

Performance testing,相比于后端,前端的性能测试就要简单不少,并且已经有比较成熟的测试工具,其目标就是花尽可能短的时间加载完整个页面。为了提高前端的性能,要从多个方面入手,不仅仅是JS代码优化这一块,比如还要减少资源的请求数目、异地部署CDN、压缩资源、优先加载页面中重要的部分(准确地说这只算是提高用户体验,但提高性能目的不就是优化用户体验嘛)等。当然,现在前端的大部分方面都已经有比较成熟的优化解决方案了,比如webpack打包的JS代码已经做了minify,能让JS代码体积减少到原来的1/N,因此我们所最需关注的仍然回到了JS代码逻辑本身。

Read more

关于pytest测试方法的tear down方式

| Comment

最近修改别人写的pytest测试方法还真是涨了不少见识,这里主要探讨下pytest测试中怎样写tear down方法。

下面的测试函数有没有问题?

import pytest

test_data = [
    (2, 4),
    (3, 10),
]

@pytest.mark.parametrize("a,expected", test_data)
def test_square(a, expected):
    try:
        assert a * a == expected
    finally:
        print 'tear down'
Read more

A bug of pytest==2.9.2

| Comment

Problem

修以前的测试代码的时候碰到的一个老版本pytest的一个bug(或者说与新版pytest不兼容的地方),记录在这里,以防以后再碰到。

在pytest中添加了一个参数需要输入一个路径作为参数的值,像这样:

pytest --remote-path /root/tmp --ssh-username root /my/tests/folder

结果执行时,得到的pytest执行tests的路径却变成了/,即根目录。

而把这个参数去掉,则路径是正确的(即上面的/my/tests/folder)。

升级到最新版本的pytest是没有这个问题的。

原因在于:老版本的pytest解析命令行参数的代码比较蠢,它会把每一个非-开头的参数放到一起,并求取它们共同的根目录作为测试的目录(比如/tmp/a/test1/tmp/a/test2就得到/tmp/a,具体代码可以看_pytest/config.py中的get_common_ancestor函数),而实际这里这个参数是紧跟在--remote-path这个option后面的,并不是作为路径传递进去的。(根本原因在于命令行参数定义时没有区分每个option后面跟的参数个数,或者是虽然定义了,但pytest根本没有鸟这个定义。)

Solution

其实很简单。

要么,升级到最新版本的pytest。

要么,option后面的参数以等号来连接,而不是空格:

pytest --remote-path=/root/tmp --ssh-username=root /my/tests/folder

GraphQL初窥

| Comment

What is GraphQL?

GraphQL是Facebook两年前发布的一个后端API的查询语言(即名称中的QL的含义),但不要被它名字中的Graph所迷惑,它和图表并没有什么关系。

关于API的查询其实我们并不陌生,比如http://localhost/messages?limit=20&output_mode=JSON,url中的问号后面的部分会被RESTful的后端解析成参数,进而可以返回对应参数的结果。当然,传统的API查询只是在每一个endpoint(即url路径)下面来单独进行的,比如/messages下面需要一个按照日期排序的查询参数,而其他的endpoint则未必需要这个参数。

不同于RESTful的API设计模式中用不同的endpoint来表示不同的资源,GraphQL中所有的请求都会发送到同一个endpoint上(假设就叫/graphql),而把请求的目标等信息全部放在了请求参数当中(比如/graphql?query={messages})。

因此,GraphQL并不是重新定义了一种协议,它只是在现有协议上的一种查询语言,我们只需要在server端定义好schema,在client端只需要根据这些schema来发送查询的请求就可以了。

GraphQL的生态圈还是挺丰富的。在server端,GraphQL有很多语言的实现,比如JavaScript的GraphQL.js,在client端,关于ReactJS有专门的官方的实现叫做Relay

Read more

Test React app with Karma

| Comment

karma-logo

Why Karma?###

前端的工具真的太多了,多的有点让人眼花缭乱。问题是我们真的需要这么多的工具吗?我觉得对于一个成熟的需要长期更新维护的代码库而言,是的,真的需要😂,最起码每一类工具总得需要选择一个来使用。而对于那些“一次性”的作品,我觉得很多工具大可省略不用(它们甚至连测试代码都可以不需要)。而Karma就是属于那一类可用可不用的工具。这类可用可不用的工具有一些共性,它们要么是为了解决因项目复杂度提高而产生的问题(小项目可以不用),要么是为了提高开发的效率(不那么关心效率的话可以不用)。

Karma正是为效率而生。

我们先回忆下现在大部分的后端测试流程,应该是像下面这样:

代码改动 => 执行测试 ==Pass=> 发布
   ^          |
   |==Fail====|

具体代码改动多少来执行一次测试则各个项目都有所不同了。一个比较普遍的做法是,在产品发布较大的版本变更之前,执行一到两次full regression test(也就是所有测试都要执行);在代码要合并(或提交)到主要的代码分支上时,执行smoke test(当然如果full regression test耗时短的话,也可以在这里执行full regression)(这里通常是和CI集成在一起的,不需要手动去执行测试)。

Read more
| Page 11 of 25 |