<pre id="ff7yo"></pre>

      <form id="ff7yo"><legend id="ff7yo"></legend></form>
        <nav id="ff7yo"><listing id="ff7yo"></listing></nav><nav id="ff7yo"></nav>

        <nav id="ff7yo"><listing id="ff7yo"></listing></nav>
        <small id="ff7yo"></small><nav id="ff7yo"><dd id="ff7yo"></dd></nav>
      1. <nav id="ff7yo"></nav>
          <form id="ff7yo"></form><nav id="ff7yo"></nav>
          <nav id="ff7yo"></nav>
          <sub id="ff7yo"></sub>
          更多課程 選擇中心

          軟件測試培訓
          達內IT學院

          400-111-8989

          面向開發的測試技術(一):Mock

          • 發布:軟件測試培訓
          • 來源:軟件測試教程
          • 時間:2017-09-01 15:18

          引子:自上世紀末Kent Beck提出TDD(Test-Driven Development)開發理念以來,開發和測試的邊界變的越來越模糊,從原本上下游的依賴關系,逐步演變成你中有我、我中有你的互賴關系,甚至很多公司設立了新的QE(Quality Engineer)職位。和傳統的QA(Quality Assurance)不同,QE的主要職責是通過工程化的手段保證項目質量,這些手段包括但不僅限于編寫單元測試、集成測試,搭建自動化測試流程,設計性能測試等。可以說,QE身上兼具了QA的質量意識和開發的工程能力。從這篇開始,我會從開發的角度分三期聊聊QE這個亦測試亦開發的角色所需的基本技能。

          1 什么是Mock?

          軟件測試領域,Mock的意思是模擬,簡單來說,就是通過某種技術手段模擬測試對象的行為,返回預先設計的結果。這里的關鍵詞是預先設計,也就是說對于任意被測試的對象,可以根據具體測試場景的需要,返回特定的結果。打個比方,就像BBC紀錄片里面的假企鵝,可以根據拍攝需要作出不同的反應。

          2 Mock有什么用?

          理解了什么是Mock,再來看Mock有哪些用途。首先,Mock可以用來解除測試對象對外部服務的依賴(比如數據庫,第三方接口等),使得測試用例可以獨立運行。不管是傳統的單體應用,還是現在流行的微服務,這點都特別重要,因為任何外部依賴的存在都會極大的限制測試用例的可遷移性和穩定性。可遷移性是指,如果要在一個新的測試環境中運行相同的測試用例,那么除了要保證測試對象自身能夠正常運行,還要保證所有依賴的外部服務也能夠被正常調用。穩定性是指,如果外部服務不可用,那么測試用例也可能會失敗。通過Mock去除外部依賴之后,不管是測試用例的可遷移性還是穩定性,都能夠上一個臺階。

          Mock的第二個好處是替換外部服務調用,提升測試用例的運行速度。任何外部服務調用至少是跨進程級別的消耗,甚至是跨系統、跨網絡的消耗,而Mock可以把消耗降低到進程內。比如原來一次秒級的網絡請求,通過Mock可以降至毫秒級,整整3個數量級的差別。

          Mock的第三個好處是提升測試效率。這里說的測試效率有兩層含義。第一層含義是單位時間運行的測試用例數,這是運行速度提升帶來的直接好處。而第二層含義是一個QE單位時間創建的測試用例數。如何理解這第二層含義呢?以單體應用為例,隨著業務復雜度的上升,為了運行一個測試用例可能需要準備很多測試數據,與此同時還要盡量保證多個測試用例之間的測試數據互不干擾。為了做到這一點,QE往往需要花費大量的時間來維護一套可運行的測試數據。有了Mock之后,由于去除了測試用例之間共享的數據庫依賴,QE就可以針對每一個或者每一組測試用例設計一套獨立的測試數據,從而很容易的做到不同測試用例之間的數據隔離性。而對于微服務,由于一個微服務可能級聯依賴很多其他的微服務,運行一個測試用例甚至需要跨系統準備一套測試數據,如果沒有Mock,基本上可以說是不可能的。因此,不管是單體應用還是微服務,有了Mock之后,QE就可以省去大量的準備測試數據的時間,專注于測試用例本身,自然也就提升了單人的測試效率。

          3 如何Mock?

          說了這么多Mock的好處,那么究竟如何在測試中使用Mock呢?針對不同的測試場景,可以選擇不同的Mock框架。

          3.1 Mockito

          如果測試對象是一個方法,尤其是涉及數據庫操作的方法,那么Mockito可能是最好的選擇。作為使用最廣泛的Mock框架,Mockito出于EasyMock而勝于EasyMock,乃至被默認集成進spring Testing。其實現原理是,通過CGLib在運行時為每一個被Mock的類或者對象動態生成一個代理對象,返回預先設計的結果。集成Mockito的基本步驟是:

          標記被Mock的類或者對象,生成代理對象

          通過Mockito API定制代理對象的行為

          調用代理對象的方法,獲得預先設計的結果

          下面是我GitHub上的示例工程里的一個例子,

          @RunWith(SpringRunner.class)

          @SpringBootTest

          public class SignonServiceTests {

          // 測試對象,一個服務類

          @Autowired

          private SignonService signonService;

          // 被Mock的類,被服務類所依賴的一個DAO類

          @MockBean

          private SignonDao dao;

          @Test

          public void testFindAll() {

          // SignonService#findAll()內部會調用SignonDao#findAll()

          // 如果不做定制,所有被Mock的類默認返回空

          List<Signon> signons = signonService.findAll();

          assertTrue(CollectionUtils.isEmpty(signons));

          // 定制返回結果

          Signon signon = new Signon();

          signon.setUsername("foo");

          when(dao.findAll()).thenReturn(Lists.newArrayList(signon));

          signons = signonService.findAll();

          // 驗證返回結果和預先設計的結果一致

          assertEquals(1, signons.size());

          assertEquals("foo", signons.get(0).getUsername());

          }

          }

          從上面的測試用例可以看到,通過Mock服務類所依賴的DAO類,我們可以跳過所有的數據庫操作,任意定制返回結果,從而專注于測試服務類內部的業務邏輯。這是傳統的非Mock測試所難以實現的。

          注意:Mockito不支持Mock私有方法或者靜態方法,如果要Mock這類方法,可以使用PowerMock。

          3.2 WireMock

          如果說Mocketo是瑞士軍刀,可以Mock Everything,那么WireMock就是為微服務而生的倚天劍。和處在對象層的Mockito不同,WireMock針對的是API。假設有兩個微服務,Service-A和Service-B,Service-A里的一個API(姑且稱為API-1),依賴于Service-B,那么使用傳統的測試方法,測試API-1時必然需要同時啟動Service-B。如果使用WireMock,那么就可以**在Service-A端**Mock所有依賴的Service-B的API,從而去掉Service-B這個外部依賴。

          同樣看一個我GitHub上的示例工程里的一個例子,

          @RunWith(SpringRunner.class)

          @WebMvcTest(VacationController.class)

          public class VacationControllerTests {

          // Mock被依賴的另一個微服務

          @Rule

          public WireMockRule wireMockRule = new WireMockRule(3001);

          @Autowired

          private MockMvc mockMvc;

          @Autowired

          private ObjectMapper objectMapper;

          @Before

          public void before() throws JsonProcessingException {

          // 定制返回結果

          JsonResult<Boolean> expected = JsonResult.ok(true);

          stubFor(get(urlPathEqualTo("/api/vacation/isWeekend"))

          .willReturn(aResponse()

          .withStatus(OK.value())

          .withHeader(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE)

          .withBody(objectMapper.writeValueAsString(expected))));

          }

          @Test

          public void testIsWeekendProxy() throws Exception {

          // 構造請求參數

          VacationRequest request = new VacationRequest();

          request.setType(PERSONAL);

          OffsetDateTime lastSunday = OffsetDateTime.now().with(TemporalAdjusters.previous(SUNDAY));

          request.setStart(lastSunday);

          request.setEnd(lastSunday.plusDays(1));

          MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/vacation/isWeekend");

          request.toMap().forEach((k, v) -> builder.param(k, v));

          JsonResult<Boolean> expected = JsonResult.ok(true);

          mockMvc.perform(builder)

          // 驗證返回結果和預先設計的結果一致

          .andExpect(status().isOk())

          .andExpect(content().contentType(APPLICATION_JSON_UTF8))

          .andExpect(content().string(objectMapper.writeValueAsString(expected)));

          }

          }

          和Mockito類似,在測試用例中集成WireMock的基本步驟是:

          聲明代理服務,以替代被Mock的微服務

          通過WireMock API定制代理服務的返回結果

          調用代理服務,獲得預先設計的結果

          值得一提的是,除了API方式的集成,WireMock還支持以Jar包的形式獨立運行,從配置文件中加載預先設計的響應結果,以替代被Mock的微服務。更多信息可以參閱官方文檔。

          其他類似的Mock API的框架還有OkHttp的mockwebserver,moco和mockserver。mockwebserver也屬于嵌入式Mock框架的范疇,但功能過于簡單。moco,mockserver雖然功能完善,但需要獨立部署,和WireMock相比不具有優勢。

          4 小結

          以上就是我對Mock技術的一些見解,歡迎你到我的留言板分享,和大家一起過過招。最后還要說一句,Mock技術雖然強大,但主要還是適用于單元測試,在集成測試,性能測試,自動化測試等其他測試領域使用并不多。

          預約申請免費試聽課

          填寫下面表單即可預約申請免費試聽!怕錢不夠?可就業掙錢后再付學費! 怕學不會?助教全程陪讀,隨時解惑!擔心就業?一地學習,可全國推薦就業!

          上一篇:軟件測試如何提交一個有質量的bug?
          下一篇:面向開發的測試技術(二):性能測試

          軟件測試培訓都包含哪些基礎知識?

          軟件測試培訓學什么

          UI自動化到底是難是易?

          軟件測試原則的6個基本原則

          • 掃碼領取資料

            回復關鍵字:視頻資料

            免費領取 達內課程視頻學習資料

          • 視頻學習QQ群

            添加QQ群:1143617948

            免費領取達內課程視頻學習資料

          Copyright ? 2021 Tedu.cn All Rights Reserved 京ICP備08000853號-56 京公網安備 11010802029508號 達內時代科技集團有限公司 版權所有

          選擇城市和中心
          黑龍江省

          吉林省

          河北省

          陜西省

          湖南省

          貴州省

          云南省

          廣西省

          海南省

          神马影院-战旗影院-首播影院-新视觉影院-在线观看中文字幕dvd播放 百度 好搜 搜狗
          <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>