This is Shi Jie. Nice to meet you.

Better qulity, better life

用户研究与表达

——用设计的方法看看市场

讲师项目及感悟

A session from ThoughWorker 陈思(UX)

  1. 某客户

  2. 微软新输入设备设计:掀开盖头(扩展描述方法)

    • unconvering feelings。设计输入设备,将问题转化为对人的描述——对产品特性、特点、定位。

    • unconvering dreams。想象他人问题的解决——产品的能力。跳出了自己,对别人的描述。

  3. 可持续发展的旅行奢侈品设计

    • 对产品的需求访谈:主观 -> 客观,具体。

    • 对产品的定义:唯一性。这个的产品是唯一能做XX的XX。

练习:

产品(航班纵横、非常准、12306),人物形象,人物故事,产品定义。(产品和人合二为一)

用户研究的过程

  1. 确立主旨

    • 为什么要调研,需要针对哪些具体的方面(业务范畴,参与人员)

    • 客户是干什么的

    • 客户需要什么样的调研

      • 客户的自我分析:帮他创造出更好的形象,也可以让他们相信TW对他们有足够的了解,已经帮他们策划好了一条正确的金光大道

      • 分析客户的用户:行业的熟知程度,足以支撑我们为他们营造的那条金光大道是可行可信的

  2. 搜集素材

    • 客户的自我分析:

      • 他们怎么表达自己?

      • 他们怎么描述自己的服务?

      • 他们怎么描述自己的竞争对手?

    • 分析客户的用户:

      • 分析客户的行为

      • 什么时候会需要我们的客户,什么时候不需要,什么时候犹豫,得到客户的服务/产品后,怎么反馈和描述这个过程

      • 分析客户与用户接触环节上的其他party

      • 这些party对客户服务用户的过程有什么影响与反馈,他们是否有potential去促进这个过程

    • 分析竞争对手:

      • 竞争对手怎么表达自己?怎么描述自己的服务?怎样描述我们的客户?

      • 我们的客户的核心价值在竞争对手中是否已经脱颖而出?

    tips: social media。抱怨和缺点

  3. 下笔之前

    • 总结Search过程中的以下元素

      • 我被什么shock到了?抓住兴奋点:天哪!原来是这样!这个会shock你 就会惊艳你的客户

      • 什么东西反复出现?也许是根基、新兴的方向、基础理论。不能忽略

      • 什么东西可以合并

      • 什么东西在我的脑海里,可是在第二步(search)中却从未被提到?这里也许包含有机会。

    • 面对竞争对手

      • 怎样以他为榜样

      • 怎样站在他的肩膀上起跳

    • 方案雏形

      unconvering your feelings & dreams

某客户

  1. 6~8个人就能发现80%的问题(定性的访谈,非定量)

  2. 报告结构

    • The general picture

    • Customs Archetypes

    • Competitors Analysis

    • Insights & Suggestions

自我评价 Critical mind

Notes

  1. 用户研究,限定了用户(中国、俄罗斯)、行为(购物)、地点(境外)、内容(退税)

  2. 报告结构。完整、讲故事、相似句式。。。

    • The general picture

    • Customs Archetypes

    • Competitors Analysis

    • Insights & Suggestions

  3. 报告tips

  4. From Kai sang:

    • 发散、搜集资料。现成的研究报告

    • 创建文件夹。对资料进行分类

    • 形成观点。 * 有观点,找素材。 * 从素材找观点

    • 粗略文档。从各处找有用材料进行填充、堆积。非精致的,有文档雏形即可

    • 精致文档。素材修饰

    • 雕刻文字

    • 版式修正

Retro

Consumer-Driven Contracts Test - Pact & Pacto

实施microservices1 (小、松耦合、多服务、多语言、自动部署、易扩展、易集成、分布式…)架构后,测试变成为了一个难题,如何在多语言、多系统、甚至异步与动态消息的情况下进行测试?如何在build(构建)中进行自动化测试?如何进行集成测试2

很多人会想到一些名词/工具:stub, mock, fake, dummy, spy, WebMock, vcr, mountebank…类似名词有很多,这些工具的思路也都类似,即在服务提供方和服务消费者之间,模拟/拦截消费者的请求,伪造一个结果请求结果返回给消费者,就如Martin Fowler说的

use to stub out parts of a system for testing

他给这些名词一个通用的叫法: TestDouble

Test Double is a generic term for any case where you replace a production object for testing purposes

replace,替代。即在测试中,对真实的对象进行替代。

但是,这种方式非常有局限性:

  1. TestDouble最重要的使用场景之一就是,与一个外部服务(external service)进行交互。但是你使用的double是否真的精确地代表了外部服务?如果外部服务改变了,你的测试又会发生什么?

    一个解决办法是,在自己的测试中使用double,同时定期的运行另外一套测试集,调用真实的外部服务,来查看外部服务的返回,是否与double测试中的相同。在Martin Fowler的blog中,称之为Tntegration Contract Test

    是不是觉得很麻烦?即使这样,还是需要在一部分测试中真实地调用外部服务。在复杂的多服务系统中(如microservices),这样做不仅很困难,而且成本非常高(也许你得为这些测试准备一套完整的环境)。

  2. TestDouble更适用于测试金字塔中的底层测试。对于UI层面的模拟用户的测试、集成测试,尤其是集成的自动化测试该怎么办呢?在microservices这种架构下,又该怎么办呢?

Consumer-Driven Contracts Test就应运而生。PactPacto都是这种消费者驱动的契约测试的产物。

每个消费者在一个单独的契约中,描述对服务提供者的期望。服务提供方在自己的测试集中,对这些“期望”进行校验。服务提供方在做出任何改变的时候,只要能保证满足消费者不对其产生影响即可。一旦对任何消费者产生影响,在正式发布前就可以知晓,而且只需要与那些会产生的影响的消费者进行协商即可。

这里的Contracts分为三部分3

  1. 提供者契约(Provider contracts)——提供者契约是我们最为熟悉的一种的服务契约,参考 WSDL+XML Schema+WS-Policy。顾名思义,提供者契约是以提供者为中心的。提供者规定了它要提供什么;然后,各消费者便将自己绑定到这个一成不变的契约上。不论消费者实际需要多少功能,消费者接受了提供者契约,就将自己与该提供者的全体功能耦合起来了。

  2. 消费者契约(Consumer contracts)——另一方面,消费者契约是对一个消费者的需求更为精确的描述。消费者契约描述了,在一次具体交互场合下,提供者功能中消费者需要的特定部分。消费者契约可被用来标注一个现有的提供者契约,另外消费者契约也有助于发现一个现今尚未规定的提供者契约。

  3. 消费者驱动的契约(Consumer-driven contracts)——消费者驱动的契约描述的是服务提供者向其所有当前消费者承诺遵守的约束。一旦各消费者把自己的具体期望告知提供者,消费者驱动的契约就被创建了。在提供者方面创建的约束,确定了一个消费者驱动的契约。若提供者接受了一个消费者驱动的契约,那么它只需保证已有约束仍能得到满足,即可自行改进与修改其服务。

现在我们看看PactPacto这两个测试框架是如何实现的。

Pact

Pact为服务消费者提供了API,用来定义消费者对服务提供方的http请求、以及期望的http响应。这些期望被用在消费者的spec测试中,来mock服务提供方。所有的交互都会被记录下,然后在服务提供方的spec测试中回放,来确保服务提供方确实提供了消费者所期望的响应。

这使得对于一个集成场景,契约的两方都可以快速、独立地进行单元测试。

工作原理4

pact-step1.png

Pact以gem的形式提供,gem地址:https://rubygems.org/gems/pact

使用方法:https://github.com/realestate-com-au/pact#installation

一些最佳实践:Pact-best-practices

Example

Pacto

Pacto包含两部分,request clause和response clause。

Request clause定义了消费者发送给服务提供方的请求中必须包含的信息,这些信息将被用于一个渲染service。通常包含了http头、需要的参数、以及请求体(json形式)。

Response clause定义了服务提供方需要返回给消费者的信息,从而成功完成一次事务。通常包含请求头和请求体(json形式)。

通常通过产生、校验、服务打桩三部分。

使用方法:https://github.com/thoughtworks/pacto#usagehttp://thoughtworks.github.io/pacto/usage/

Exmaple API

Sample APP

区别:

  1. Pacto仅支持json服务,原生支持Ruby,对于非Ruby项目,提供了Pacto Server

    Pact支持Ruby, JVM(pact-jvm), .net的消费者,Ruby mock server使用了Javascript进行包装。对于非ruby的服务提供方,Pact提供了Pact Provider Proxy

  2. Pacto不支持多状态码验证(如200、201)。Pact允许在服务提供者不同状态下,生成同样的请求,允许在同样的endpoint上测试不同的http响应码,或者在不同状态下测试相同的资源。

  3. Pacto通过录制与现有服务的交互,可以录制契约。不用手工编写,使得契约非常容易创建。

  4. Pacto一旦录制完成,契约就是静态的,既可以校验服务消费者,也可以校验服务提供方。

    Pact的契约是动态生成的中间产物,更容易维护why?

  5. Pact支持正则表达匹配。

  6. Pact有Pact Broker,提供了自动生成的文档、网络图,使得在产品环境和最新版本(消费者和提供者)间进行交叉测试成为可能,从而将消费者和提供者的发布循环解耦。

总结:

  1. 契约录制功能,使得当需要对一个现有第三方服务打桩的时候,Pacto成了更好的选择。在这种情况下,服务提供方状态的缺失、正则匹配可能无关紧要,因为你不可能在服务方创建一套数据,而不使用当前测试的接口。

  2. 对于服务提供方不还不存在的新项目来说,Pact可能更好,因为消费者的功能可以驱动出服务提供方的需求。

参考资料:

  1. Lightening Talk: Auckland Continuous Delivery Meetup [Sept 2014] - Pact: Consumer-Driven Contract Testing (Integrated Tests Are A Scam)

  2. realestate.com.au:http://techblog.realestate.com.au/testing-interactions-with-web-services-without-integration-tests-in-ruby/

  3. 微服务测试

    microservice-testing-summary.png

  4. Pact and Pacto


  1. 关于Microservices,参阅ThoughtWorks技术雷达Martin Fowler的blog

  2. Martin Flower的微服务测试

  3. 这三种契约的描述,摘自InfoQ的文章用消费者驱动的契约进行面向服务开发

  4. 这两张图片来自Simplifying Micro-Service testing with Pacts

使用octopress创建个人博客

Refer to this link

开始之前的准备工作:安装Git、ruby、bundler。

准备

  1. 下载octopress: git clone git://github.com/imathis/octopress.git octopress

  2. 进入octopress目录,执行rake install

创建部署

  1. 创建一个新的Github的空repo,并且命名为iamshijie.github.io

  2. 进入自己下载的octopress的目录并执行rake setup_github_pages。当提示输入repo地址时,输入上一步创建的git地址:git@github.com:Shi-Jie/iamshijie.github.io.git

  3. 继续在octopress目录下执行rake generate 。此时,打开http://iamshijie.github.io.git就能看到blog原型。再执行rake deploy

  4. git提交。本别执行git add .git commit -m 'your message'git push origin source

  5. 修改个人blog的默认分支为source,而非master git link

创建博客

这部分可以参考之前在QA community的blog

  1. clone博客repo到本地:git clone git@github.com:iamshijie/iamshijie.github.io.git

    确保你的默认分支是source。即git status后看到的是

     Shi-Jie:iamshijie.github.io shijie$ git status
     On branch source
     Your branch is up-to-date with 'origin/source'.
     nothing to commit, working directory clean
    
  2. 本地生成发布目录,执行rake setup_github_pages交互时输入git@github.com:Shi-Jie/iamshijie.github.io.git

  3. 执行rake install。安装默认主题。

  4. 创建新post。在repo下执行rake new_post["How to create blog with octopress"]

  5. 修改上一步生成的markdown文件,直接在默认生成的内容后进行添加编辑:

     ---
     layout: post
     title: "How to setup blog with octopress"
     date: 2015-01-21 09:16:24 +0800
     comments: true
     categories:
     ---
    
  6. 使用rake preview进行预览

  7. 确认无误后。使用rake gen_deploy发布的master。完成后,就可以在个人http://iamshijie.github.io看到效果

  8. 将改动提交到source分支

     git add .
     git commit -m 'Post my first blog. - ShiJie'
     git push