Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 日韩大片免费看,91madou传媒在线观看,高清日韩在线

          整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          分享7個最佳的JavaScript測試庫,提高你的工

          分享7個最佳的JavaScript測試庫,提高你的工作效率

          載說明:原創(chuàng)不易,未經(jīng)授權(quán),謝絕任何形式的轉(zhuǎn)載

          創(chuàng)建一個不會崩潰的應(yīng)用程序

          在現(xiàn)代軟件開發(fā)中,編寫和維護高質(zhì)量的測試用例已經(jīng)成為我們?nèi)粘9ぷ鞯闹匾糠?。而JavaScript作為全球最流行的編程語言之一,擁有大量的庫和框架,能夠幫助我們更好地進行測試。

          在這篇文章中,我將向大家介紹七個優(yōu)秀的JavaScript測試庫,包括Jest、Sinon、Detox、Cucumber、Stryker、TestDouble和Mockttp。這些庫在各自的領(lǐng)域中都有出色的表現(xiàn),如單元測試、功能測試、模擬、集成測試和突變測試等。通過本文的介紹,我希望你能更深入地了解這些庫,找到適合你項目的測試工具。

          1、Jasmine

          這是GitHub上星標(biāo)超過15500的頂級庫之一。如果你想在你的項目中進行行為驅(qū)動開發(fā)(Behavior Driven Development)測試,那么這將是一個非常好的資源。它不依賴于瀏覽器、DOM或任何JavaScript框架,因此非常適合用于網(wǎng)站、Node.js項目,或者任何能運行JavaScript的地方。你可以點擊這里查看這個庫。

          https://github.com/jasmine/jasmine

          使用示例

          Jasmine是一個用于JavaScript代碼的行為驅(qū)動開發(fā)(BDD)測試框架。它無需DOM和它可以在任何JavaScript支持的環(huán)境中運行,包括Node.js和瀏覽器。

          首先,你需要安裝Jasmine。在Node.js環(huán)境中,你可以通過npm(Node包管理器)來安裝:

          npm install --save-dev jasmine

          安裝完Jasmine后,你可以在你的項目中創(chuàng)建一些測試文件。這些測試文件通常稱為"spec"文件,在這些文件中你可以寫下測試用例。下面是一個簡單的示例:

          // myFunction.spec.js
          const myFunction=require('./myFunction.js');
          
          describe("myFunction", function() {
            it("應(yīng)該返回 'Hello, World!'", function() {
              expect(myFunction()).toEqual('Hello, World!');
            });
          });
          

          在上述代碼中,describe函數(shù)定義了一組相關(guān)的測試,it函數(shù)定義了一個單獨的測試。expect函數(shù)和toEqual函數(shù)一起構(gòu)成一個測試斷言,它們判斷myFunction的返回值是否為Hello, World!。

          假設(shè)我們有如下的被測試函數(shù):

          // myFunction.js
          function myFunction() {
            return 'Hello, World!';
          }
          
          module.exports=myFunction;

          當(dāng)你想運行測試時,可以在終端中運行以下命令:

          npx jasmine myFunction.spec.js

          如果myFunction函數(shù)的行為符合我們的預(yù)期(也就是返回Hello, World!),那么測試就會通過。如果函數(shù)的行為與我們的預(yù)期不符,那么測試就會失敗,并顯示一條描述失敗原因的消息。

          以上就是對Jasmine庫的基本介紹和示例。你可以訪問其GitHub頁面獲取更多的信息和詳細(xì)的文檔。

          2、Sinon

          這是一個獨立的庫,用于在JavaScript測試中創(chuàng)建測試替身(偵查、樁和模擬)。它通過提供工具來驗證函數(shù)調(diào)用、控制行為等,幫助你編寫隔離的測試。它在GitHub上有超過9000顆星標(biāo)。你可以點擊這里查看這個庫。

          https://github.com/sinonjs/sinon

          3、Detox

          如果你想對你的移動應(yīng)用進行測試,這將是一個非常好的資源。高速度的原生移動開發(fā)需要我們采用持續(xù)集成工作流,這就意味著我們對人工質(zhì)量保證的依賴需要大大降低。這個庫可以在真實設(shè)備或模擬器上運行你的移動應(yīng)用進行測試,就像真正的用戶一樣與它進行交互。它在GitHub上有超過10000顆星標(biāo)。你可以點擊這里查看這個庫。

          https://github.com/wix/Detox

          使用示例

          Detox是一個用于端到端測試React Native和其他原生移動應(yīng)用的庫。與其他庫不同,Detox提供了一種方式來自動模擬真實用戶的行為并且測試應(yīng)用在真實設(shè)備或模擬器上的表現(xiàn)。

          首先,你需要在你的項目中安裝Detox和它的命令行工具。在Node.js環(huán)境中,你可以使用npm(Node包管理器)來安裝:

          npm install detox --save-dev
          npm install -g detox-cli

          然后,你需要在你的項目中配置Detox。在你的package.json文件中,你需要添加一個名為"detox"的新字段:

          "detox": {
            "configurations": {
              "ios.sim.debug": {
                "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/YourApp.app",
                "build": "xcodebuild -project ios/YourApp.xcodeproj -scheme YourApp -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
                "type": "ios.simulator",
                "device": {
                  "type": "iPhone 11"
                }
              }
            }
          }
          

          在上述配置中,我們定義了一個測試配置,命名為"ios.sim.debug"。這個配置指定了你的應(yīng)用在哪里構(gòu)建、應(yīng)用的類型以及你想在哪種設(shè)備上運行測試。

          接下來,你可以編寫一些端到端的測試用例。這些測試用例會在你指定的設(shè)備上運行你的應(yīng)用并模擬真實用戶的行為。以下是一個簡單的示例:

          // e2e/firstTest.spec.js
          describe('Example', ()=> {
            beforeEach(async ()=> {
              await device.reloadReactNative();
            });
          
            it('should have welcome screen', async ()=> {
              await expect(element(by.id('welcome'))).toBeVisible();
            });
          });
          

          在上述代碼中,我們首先調(diào)用device.reloadReactNative()來確保每個測試用例開始時應(yīng)用都是在一個新的狀態(tài)。然后我們使用expect和toBeVisible來斷言歡迎界面是否可見。

          當(dāng)你想運行測試時,你需要先構(gòu)建你的應(yīng)用,然后再運行測試:

          detox build --configuration ios.sim.debug
          detox test --configuration ios.sim.debug

          如果你的應(yīng)用的行為符合我們的預(yù)期,那么測試就會通過。如果應(yīng)用的行為與我們的預(yù)期不符,那么測試就會失敗,并顯示一條描述失敗原因的消息。

          以上就是對Detox庫的基本介紹和示例。你可以訪問其GitHub頁面獲取更多的信息和詳細(xì)的文檔。

          4、Cucumber

          Cucumber是一個運行用簡單語言編寫的自動化測試的工具。因為它們是用簡單語言編寫的,所以你的團隊中的任何人都可以閱讀。因為任何人都可以閱讀,所以你可以使用它們來幫助提高團隊的溝通、協(xié)作和信任。這是Cucumber的JavaScript實現(xiàn)。它在GitHub上有超過4500顆星標(biāo)。你可以點擊這里查看這個庫。

          https://github.com/cucumber/cucumber-js

          使用示例

          Cucumber是一種行為驅(qū)動開發(fā)(BDD)的工具,它允許開發(fā)者用簡潔的、近乎自然語言的文本語句(如英語)來描述應(yīng)用程序的行為,然后可以將這些語句轉(zhuǎn)換為可執(zhí)行的測試。

          首先,你需要在你的項目中安裝Cucumber。在Node.js環(huán)境中,你可以使用npm(Node包管理器)來安裝:

          npm install --save-dev @cucumber/cucumber

          接下來,你需要創(chuàng)建一個功能文件(通常以 .feature 結(jié)尾)。這個文件使用一種名為Gherkin的語言來描述應(yīng)用程序的行為。例如,你可能有一個如下的功能文件:

          # myFeature.feature
          Feature: Saying hello
            Scenario: User says hello
              Given the user has opened the application
              When the user says hello
              Then the application should reply with "Hello, User!"

          然后,你需要創(chuàng)建一些步驟定義(step definitions)。步驟定義是用JavaScript編寫的函數(shù),這些函數(shù)會被Cucumber用來執(zhí)行功能文件中的每一步。例如,你可能有一個如下的步驟定義文件:

          // mySteps.js
          const { Given, When, Then }=require('@cucumber/cucumber');
          
          let appOpen=false;
          let saidHello=false;
          
          Given('the user has opened the application', function () {
            appOpen=true;
          });
          
          When('the user says hello', function () {
            if (appOpen) saidHello=true;
          });
          
          Then('the application should reply with "Hello, User!"', function () {
            if (appOpen && saidHello) {
              console.log('Hello, User!');
            }
          });

          最后,你可以通過Cucumber CLI來運行你的功能文件:

          npx cucumber-js myFeature.feature

          以上就是對Cucumber庫的基本介紹和示例。你可以訪問其GitHub頁面獲取更多的信息和詳細(xì)的文檔。

          5、Stryker

          變異測試會對你的代碼進行更改,然后針對更改后的代碼運行你的單元測試。預(yù)期你的單元測試現(xiàn)在會失敗。如果它們沒有失敗,那可能意味著你的測試并沒有足夠覆蓋到代碼。正如你所猜測的,這個庫將幫助你在項目中進行變異測試。它在GitHub上有超過2000顆星標(biāo)。你可以點擊這里查看這個庫。

          https://github.com/stryker-mutator/stryker-js

          使用示例

          Stryker是一個變異測試框架,可以幫助你提高單元測試的質(zhì)量。變異測試的工作原理是通過對代碼進行小的修改(稱為“變異”),然后運行你的單元測試以查看哪些修改沒有被測試捕獲,這可以幫助揭示代碼覆蓋率的盲點。

          首先,你需要在你的項目中安裝Stryker和它需要的插件。在Node.js環(huán)境中,你可以使用npm(Node包管理器)來安裝:

          npm install --save-dev @stryker-mutator/core @stryker-mutator/mocha-runner @stryker-mutator/javascript-mutator

          在上面的示例中,我們安裝了Stryker的核心庫,用于運行Mocha測試的運行器以及JavaScript變異器。

          然后,你需要創(chuàng)建一個Stryker配置文件。這個文件名通常為stryker.conf.js,并且應(yīng)該位于項目的根目錄下。在這個文件中,你可以定義Stryker應(yīng)該如何運行你的測試和創(chuàng)建變異。

          // stryker.conf.js
          module.exports=function(config){
            config.set({
              mutator: "javascript",
              packageManager: "npm",
              reporters: ["clear-text", "progress"],
              testRunner: "mocha",
              transpilers: [],
              coverageAnalysis: "off",
              mutate: ["src/**/*.js"],
            });
          };
          

          在上述代碼中,我們告訴Stryker使用JavaScript變異器,使用npm作為包管理器,以及使用Mocha作為測試運行器。我們還告訴Stryker需要變異哪些文件。

          現(xiàn)在,你可以運行Stryker來執(zhí)行變異測試了:

          npx stryker run

          Stryker會生成一份報告,顯示每個變異是否被測試覆蓋。如果你的單元測試沒有捕獲到某個變異,那么你可能需要增加或改進你的測試。

          以上就是對Stryker庫的基本介紹和示例。你可以訪問其GitHub頁面獲取更多的信息和詳細(xì)的文檔。

          6、TestDouble

          你在編寫JavaScript測試,并在尋找一個模擬庫來替你模擬真實的東西嗎?這是一個有自己獨特見解的,設(shè)計精心的測試替身庫。該庫旨在適用于Node.js和瀏覽器解釋器。它也是測試框架無關(guān)的,所以你可以將它放入使用Jasmine、Mocha、Tape、Jest或我們自己的teenytest的代碼庫中。它在GitHub上有超過1000顆星標(biāo)。你可以點擊這里查看這個庫。

          https://github.com/testdouble/testdouble.js

          使用示例

          TestDouble.js 是一個用于在JavaScript中創(chuàng)建測試替身(test doubles)的庫。它的設(shè)計原則是讓你能夠在單元測試中輕松地模擬或偽造(fake)依賴,從而讓你能夠更好地隔離和控制你的測試環(huán)境。

          首先,你需要在你的項目中安裝TestDouble。在Node.js環(huán)境中,你可以使用npm(Node包管理器)來安裝:

          npm install --save-dev testdouble

          接下來,你可以在你的單元測試中使用TestDouble。例如,你可以使用td.function()來創(chuàng)建一個模擬函數(shù):

          const td=require('testdouble');
          
          // 創(chuàng)建一個模擬函數(shù)
          const mockFunction=td.function();
          
          // 使模擬函數(shù)在調(diào)用時返回特定的值
          td.when(mockFunction('hello')).thenReturn('world');
          
          // 現(xiàn)在,當(dāng)你調(diào)用 mockFunction('hello') 時,它將返回 'world'
          console.log(mockFunction('hello'));  // 輸出: 'world'
          

          你也可以使用TestDouble來模擬對象,例如使用td.object()來創(chuàng)建一個模擬對象:

          const td=require('testdouble');
          
          // 創(chuàng)建一個模擬對象
          const mockObject=td.object(['method1', 'method2']);
          
          // 使模擬對象的方法在調(diào)用時返回特定的值
          td.when(mockObject.method1()).thenReturn('hello');
          
          // 現(xiàn)在,當(dāng)你調(diào)用 mockObject.method1() 時,它將返回 'hello'
          console.log(mockObject.method1());  // 輸出: 'hello'
          

          TestDouble.js 還提供了許多其他用于創(chuàng)建和管理測試替身的功能,例如驗證函數(shù)是否被調(diào)用,替換模塊等。以上就是對TestDouble庫的基本介紹和示例,你可以訪問其GitHub頁面獲取更多的信息和詳細(xì)的文檔。

          7、Mockttp

          HTTP測試是最常見且支持最好的用例。這個庫讓你能夠在JavaScript中快速、可靠、在任何地方攔截、轉(zhuǎn)換或測試HTTP請求和響應(yīng)。你可以在集成測試中使用這個庫,作為你的測試套件的一部分來攔截真實的請求,或者你可以使用它來構(gòu)建自定義的HTTP代理,捕獲、檢查和/或以任何你喜歡的方式重寫HTTP。你可以點擊這里查看這個庫。

          https://github.com/httptoolkit/mockttp

          使用示例

          Mockttp是一個強大的庫,它允許你在JavaScript中攔截、檢查和修改HTTP請求和響應(yīng)。這對于集成測試和調(diào)試HTTP通信非常有用。

          首先,你需要在你的項目中安裝Mockttp。在Node.js環(huán)境中,你可以使用npm(Node包管理器)來安裝:

          npm install --save-dev mockttp

          接下來,我們將介紹一些基本的使用方式:

          // 引入需要的庫
          const superagent=require("superagent");
          const mockServer=require("mockttp").getLocal();
          
          // 在測試開始前啟動Mock服務(wù)器,并在測試結(jié)束后關(guān)閉服務(wù)器
          beforeEach(()=> mockServer.start(8080));
          afterEach(()=> mockServer.stop());
          
          // 模擬請求,并對結(jié)果進行斷言
          it("lets you mock requests, and assert on the results", async ()=> {
              // 模擬你的端點
              await mockServer.forGet("/mocked-path").thenReply(200, "A mocked response");
          
              // 發(fā)送一個請求
              const response=await superagent.get("http://localhost:8080/mocked-path");
          
              // 對結(jié)果進行斷言
              expect(response.text).to.equal("A mocked response");
          });
          
          

          以上代碼創(chuàng)建了一個Mock服務(wù)器,并設(shè)置了一個模擬的GET請求。然后,我們發(fā)送一個實際的GET請求,并斷言返回的響應(yīng)文本是否等于我們設(shè)置的模擬響應(yīng)。

          Mockttp還提供了更多高級特性,例如:

          1. 無需指定端口,允許并行測試
          2. 驗證Mock服務(wù)器接收的請求詳情
          3. 代理請求到任何其他主機

          以下是一些更高級的示例:

          const superagent=require("superagent");
          require('superagent-proxy')(superagent);
          const mockServer=require("mockttp").getLocal();
          
          describe("Mockttp", ()=> {
              beforeEach(()=> mockServer.start());
              afterEach(()=> mockServer.stop());
          
              // 不指定端口,允許并行測試
              it("lets you mock without specifying a port, allowing parallel testing", async ()=> {
                  await mockServer.forGet("/mocked-endpoint").thenReply(200, "Tip top testing");
          
                  let response=await superagent.get(mockServer.urlFor("/mocked-endpoint"));
          
                  expect(response.text).to.equal("Tip top testing");
              });
          
              // 驗證mock服務(wù)器接收的請求詳情
              it("lets you verify the request details the mockttp server receives", async ()=> {
                  const endpointMock=await mockServer.forGet("/mocked-endpoint").thenReply(200, "hmm?");
          
                  await superagent.get(mockServer.urlFor("/mocked-endpoint"));
          
                  const requests=await endpointMock.getSeenRequests();
                  expect(requests.length).to.equal(1);
                  expect(requests[0].url).to.equal(`http://localhost:${mockServer.port}/mocked-endpoint`);
              });
          
              // 代理請求到任何其他主機
              it("lets you proxy requests made to any other hosts", async ()=> {
                  await mockServer.forGet("http://google.com").thenReply(200, "I can't believe it's not google!");
          
                  let response=await superagent.get("http://google.com").proxy(mockServer.url);
          
                  expect(response.text).to.equal("I can't believe it's not google!");
              });
          });
          

          這些示例使用了Mocha,Chai和Superagent,但并非必須使用這些:Mockttp可以與任何可以處理promise的測試工具配合使用,可以模擬來自任何庫、工具或設(shè)備的請求。

          結(jié)尾

          在這篇文章中,我們了解了七個JavaScript測試庫:Jest、Sinon、Detox、Cucumber、Stryker、TestDouble和Mockttp。每一個庫都有其獨特的功能和特點,可以幫助我們更高效地編寫和管理測試用例,確保代碼的質(zhì)量和穩(wěn)定性。

          不論你是初學(xué)者還是資深開發(fā)者,這些庫都將是你開發(fā)過程中強大的工具。我希望通過本文的介紹,你能更深入地了解這些庫,找到最適合你的工具。

          在結(jié)束本文之前,我想說,測試是軟件開發(fā)中不可或缺的一部分,選擇和掌握合適的測試工具,可以讓我們的工作變得更加輕松。最后,希望本文能對你的開發(fā)工作帶來幫助,如果你有任何問題或者建議,歡迎在評論區(qū)留言。感謝閱讀,我們下次再見。

          由于文章內(nèi)容篇幅有限,今天的內(nèi)容就分享到這里,文章結(jié)尾,我想提醒您,文章的創(chuàng)作不易,如果您喜歡我的分享,請別忘了點贊和轉(zhuǎn)發(fā),讓更多有需要的人看到。同時,如果您想獲取更多前端技術(shù)的知識,歡迎關(guān)注我,您的支持將是我分享最大的動力。我會持續(xù)輸出更多內(nèi)容,敬請期待。


          文為霍格沃茲測試學(xué)院優(yōu)秀學(xué)員關(guān)于 Jacoco 的小結(jié)和踩坑記錄。測試開發(fā)進階學(xué)習(xí),文末加群。

          一、概述

          測試覆蓋率是老生常談的話題。因為我測試?yán)碚摶A(chǔ)不是很好,這里就不提需求、覆蓋率等內(nèi)容,直奔主題,本文主要指 Java 后端的測試覆蓋率。

          由于歷史原因,公司基本不做 UT,所以對測試來說,咱最關(guān)心的還是手工執(zhí)行、接口執(zhí)行 (人工 Postman 之類的)、接口自動化、WebUI 自動化對一個應(yīng)用系統(tǒng)的覆蓋度。

          本來 Jacoco 已經(jīng)流行了很多年了,各種文檔和帖子已經(jīng)描述的很完美了,但是多數(shù)文章都是針對某一特定形式做了總結(jié)和使用。相信很多負(fù)責(zé)整個公司項目的覆蓋率任務(wù)的人們來說,還是要一種一種去研究、去應(yīng)對,入坑、出坑不厭其煩。

          也得益于今年上半年一直負(fù)責(zé)整個公司不同類型的項目的覆蓋率統(tǒng)計技術(shù)的適配,對不同形式的項目均有一定的了解,在此記錄一下,也不讓千瘡百孔的自己浪費掉這半年的精力,如果說可以幫到別人一星半點,那這篇文章就算是造福了。由于本人能力有限、表達能力有限,如有錯誤,還請大家多指正。

          二、投入覆蓋率之前的思路

          因為之前了解過一部分 Jacoco 的機制,也知道它提供了很多強大的功能,以滿足不同形式的項目。但歸根結(jié)底,Jacoco 提供了 API,可以讓大家屏蔽不同類型的項目帶來的困擾。

          Jacoco 官方的 Api 示例地址:

          https://www.Jacoco.org/Jacoco/trunk/doc/api.html

          個人認(rèn)為,以 Api 的方式來進行操作,可以有以下好處:

          可以屏蔽不同方式的構(gòu)建部署。如果你想把這個功能做成平臺,那 API 想必是很好的一種方式。

          也就是說,我只需要把 Jacoco 插樁到測試服務(wù)器上,暴露 TCP 的 IP 和端口,剩余的提取代碼執(zhí)行數(shù)據(jù)、生成覆蓋率報告,就可以用統(tǒng)一的方式進行就好了。

          眾所周知,Jacoco 官方提供了 Maven 插件方式、Ant 的 XML 方式,均有對應(yīng)的 dump 和 report 來進行覆蓋率數(shù)據(jù)的 dump 和報告生成,大家如果有興趣可以研究一下,這里不贅述。

          三、項目梳理

          由于我所在的公司是個老牌公司,項目雜亂無章,技術(shù)五花八門。至今仍然有跑在 JDK6 上的。所以我個人認(rèn)為,影響 Jacoco 使用過程的,可能存在于以下幾點。

          1. JDK 版本。

          我司現(xiàn)有 JDK6、7、8,但實際上 jdk6 是個分水嶺,其他的都基本可以用 JDK8 來適配。

          1. 構(gòu)建工具。

          我司現(xiàn)有 Maven 構(gòu)建、ANT 構(gòu)建,想必有的公司還有用 Gradle 的。

          1. 部署方式。

          Ant、Maven 插件啟動、Java -jar 啟動、Tomcat 啟動 war 包 (打包方式就隨便了)

          稍后內(nèi)容也都基于這幾種不同實現(xiàn)方式做描述。如果接觸項目多的,基本就知道,很多時候測試還是不介入測試環(huán)境的發(fā)布,這一方面源于開發(fā)的不信任,他們認(rèn)為發(fā)布還是要抓在開發(fā)自己手里;另一方面也源于測試人員能力的跟不上,至少在我司很多測試人員確實不太懂如何發(fā)布(雖然現(xiàn)在慢慢有所緩解,越來越都的測試人員都從開發(fā)手中接了過來)。

          線上部署、測試部署、開發(fā)部署,這幾個不同場景,可能用的方式都不同,至少在我接觸的項目大都是這樣。開發(fā)喜歡用插件的方式啟動部署,因為快嘛,而且 IDE 也支持,右鍵運行一下基本在 IDE 就啟動了,想想看如果你是開發(fā),在你本地 IDE 里調(diào)試的時候,需要打個 war 包然后丟到 Tomcat 里,再啟動 Tomcat,你也不太樂意。

          四、Jacoco 插樁的本質(zhì)

          廢話不多說,步入正題。Jacoco 介入部署過程的本質(zhì),就是插樁,至于怎么插樁,跟接入階段有關(guān)系??梢允蔷幾g時插樁、也可以是運行時插樁,這就是所謂 Offline 模式和 On-the-fly 模式,我們也不過多于糾結(jié),我們選擇了 on-the-fly 模式。

          所以歸結(jié)到本質(zhì),Jacoco 的 on-the-fly 模式的插樁過程,其實就是在測試環(huán)境部署的時候,讓 Jacoco 的相關(guān)工具,介入部署過程,也就是介入 class 文件的加載,在加載 class 的時候,動態(tài)改變字節(jié)碼結(jié)構(gòu),插入 Jacoco 的探針。

          本質(zhì):Jacoco 以 TCPserver 方式進行插樁的本質(zhì),就是如果應(yīng)用啟動過程中,進行了 Jacoco 插樁,且成功了。它會在你當(dāng)前這個啟動服務(wù)器中,在一個端口{$port}上,開啟一個 TCP 服務(wù),這個 TCP 服務(wù),會一直接收 Jacoco 的執(zhí)行覆蓋率信息并傳到這個 TCP 服務(wù)上進行保存。

          既然是個 TCP 服務(wù),那 Jacoco 也提供了一種以 API 的方式連接到這個 TCP 服務(wù)上,進行覆蓋率數(shù)據(jù)的 dump 操作。(細(xì)節(jié)可能描述的不是很精確,但差不多就是這么個過程。這個 TCP 服務(wù),在你沒有關(guān)閉應(yīng)用的時候,是一直開著的,可以隨時接受連接)

          再本質(zhì)一點,就是介入下面這個命令的啟動過程:

          java -jar 

          那問題就好辦了,一種一種來對應(yīng)起來。

          五、不同形式的插樁配置

          提到介入啟動過程,那就免不了提一下一個 jar 包。

          Jacocoagent.jar下載地址:

          https://www.eclemma.org/Jacoco/

          下載后解壓文件夾里,目錄如下:

          這個 Jacocoagent.jar, 就是啟動應(yīng)用時主要用來插樁的 jar 包。

          請注意不要寫錯名稱,里面有個很像的 Jacocoant.jar,這個 jar 包是用 ant xml 方式操作 Jacoco 時使用的,不要混淆。

          以測試環(huán)境部署在 Linux 服務(wù)器上為例,如果想在 Windows 上測試也可以,把對應(yīng)的值改成 Windows 上識別的即可。

          假設(shè) Jacocoagent.jar 的存放路徑為:/home/admin/Jacoco/Jacocoagent.jar

          以下都以 $JacocoJarPath 來替代這個路徑,請注意這個路徑不是死的,你可以修改。

          依然是基于上述的幾種不同方式,那我們針對不同形式·做插樁,也就是改變這幾種不同形式的底層啟動原理,也就是改動不同方式的 java 的啟動參數(shù),這對每一種啟動方式都不太一樣。但是改動 Java 啟動參數(shù)本質(zhì)也是一樣的,就是在 java -jar 啟動的時候,加入 -javaagent 參數(shù)。

          -javaagent:$JacocoJarPath=includes=*,output=TCPserver,port=2014,address=192.168.110.1"

          換成實際的信息為如下,請注意替換真實路徑,這一句是需要介入應(yīng)用啟動過程的主要代碼,針對每種不同的部署方式,需要加到不同的地方。

          -javaagent:/home/admin/Jacoco/Jacocoagent.jar=includes=*,output=TCPserver,port=2014,address=192.168.110.1

          5.1 這句話的解釋

          1. -javaagent

          JDK5 之后新增的參數(shù),主要用來在運行 jar 包的時候,以一種方式介入字節(jié)碼加載過程,如有興趣自行百度。注意后面有個冒號:

          1. /home/admin/Jacoco/Jacocoagent.jar

          需要用來介入 class 文件加載過程的 jar 包,想深入了解的,百度 “插樁” 哈。這是一個 jar 包的絕對路徑。

          1. includes=*

          這個代表了,啟動時需要進行字節(jié)碼插樁的包過濾,* 代表所有的 class 文件加載都需要進行插樁。

          假如你們公司內(nèi)部代碼都有相同的包前綴 :com.mycompany<你可以寫成:

          includes=com.mycompany.*
          1. output=TCPserver

          這個地方不用改動,代表以 TCPserver 方式啟動應(yīng)用并進行插樁。

          1. port=2014

          這是 Jacoco 開啟的 TCPserver 的端口,請注意這個端口不能被占用。

          1. address=192.168.110.1

          這是對外開發(fā)的 TCPserver 的訪問地址。可以配置 127.0.0.1, 也可以配置為實際訪問 IP。

          配置為 127.0.0.1 的時候,dump 數(shù)據(jù)只能在這臺服務(wù)器上進行 dump,就不能通過遠(yuǎn)程方式 dump 數(shù)據(jù)。配置為實際的 IP 地址的時候,就可以在任意一臺機器上 (前提是 IP 要通,不通都白瞎),通過 Ant XML 或者 API 方式 dump 數(shù)據(jù)。舉個栗子:

          我如上配置了 192.168.110.1:2014 作為 Jacoco 的 TCPserver 啟動服務(wù),那我可以在任意一臺機器上進行數(shù)據(jù)的 dump,比如在我本機 Windows 上用 API 或者 XML 方式調(diào)用 dump。

          如果我配置了 127.0.0.1:2014 作為啟動服務(wù)器,那么我只能在這臺測試機上進行 dump,其他的機器都無法連接到這個 TCPserver 進行 dump。

          1. 總結(jié):

          這句內(nèi)容,如下,格式是固定的,只有括號內(nèi)的東西方可改變,其它盡量不要動,連空格都不要多:

          -javaagent:(/home/admin/Jacoco/Jacocoagent.jar)=includes=(*),output=TCPserver,port=(2014),address=(192.168.110.1)

          比如我可以改成其他的:

          -javaagent:/home/admin/Jacoco_new/Jacocoagent.jar=includes=com.company.*,output=TCPserver,port=2019,address=192.168.110.111

          注意其他地方基本不用改動。

          5.2 war 包方式啟動

          tomcat 的 war 包方式啟動,假設(shè) tomcat 路徑為: $CATALINA_HOME=/usr/local/apache-tomcat-8.5.20,我們常用的命令存在于: $CATALINA_HOME\bin下,有 startup.sh 和 shutdown.sh(windows 請自覺改為 bat, 后續(xù)不再聲明),其實這兩個只是封裝之后的腳本,底層調(diào)用的都是 $CATALINA_HOME\bin\catalina.sh(或者 bat),如圖源碼:

          因此,只需要改動 catalina.sh 中的啟動參數(shù)即可。

          前面提到過,主要改動主要是改動 java -jar,tomcat 是通過一個 JAVA_OPTS 參數(shù)來控制額外的 java 啟動參數(shù)的,我們只需要在合適的地方把上面的啟動命令追加到 JAVA_OPTS 即可打開 catalina.sh,找到合適的地方修改 JAVA_OPTS 參數(shù):

          理論上,任何地方修改 JAVA_OPTS 參數(shù)均可,但我們實驗過后,在以下位置加入,是一定可以啟動成功的,當(dāng)然您也可以嘗試其他位置。

          JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.security.SecurityListener.UMASK=`umask`"

          源腳本中有這個注釋掉的地方,我們在下方修改 JAVA_OPTS,在其下方,加一句:

          JAVA_OPTS="$JAVA_OPTS -javaagent:$JacocoJarPath=includes=*,output=TCPserver,port=2014,address=192.168.110.1"

          改完之后如下所示:

          改完之后,就可以進行 startup.sh 的啟動了,應(yīng)用啟動成功之后,可以在服務(wù)器上進行調(diào)試,查看 TCPserver 是否真的起來了。

          判別方式如下 (該圖中是現(xiàn)有的已經(jīng)開啟的服務(wù),所以 IP 和端口跟前面的命令不一樣,這點請注意,這里只是為了展示;后續(xù)幾種方式判別方式相同,不再贅述了哈), 這個端口在應(yīng)用啟動時被占用,在應(yīng)用關(guān)閉時被釋放,這個請注意檢查:

          如此,這個端口已經(jīng)在監(jiān)聽了,證明這個測試環(huán)境已經(jīng)把 Jacoco 注入進去,那你對該測試環(huán)境的任何操作,代碼執(zhí)行信息都會被記錄到這個 ip:port 開啟的 TCP 服務(wù)中。

          5.3 Maven 命令的插件啟動方式

          在我司,有的開發(fā)會喜歡用插件方式啟動,在代碼 pom 文件層級中,運行如下命令:

          mvn clean install
          
          mvn tomcat7:run -Dport=xxx

          或者還有

          mvn clean install
          
          mvn spring-boot:run -Dport=xxx

          這兩套命令,本質(zhì)上沒什么差別,只是運行插件不一樣,具體用什么命令,如果不清楚,最好是跟開發(fā)請教一下。

          他們的意思是,在當(dāng)前代碼的 pom 文件層級運行,意思是通過 maven 的 tomcat 插件啟動這個服務(wù),這個服務(wù)啟動在端口 xxx 上,注意這個端口是應(yīng)用的訪問端口,和 Jacoco 的那個端口不是一回事。

          對這種方式注入 Jacoco,也是可以的。這種可以不用修改任何的配置文件,只需要在你啟動的時候,臨時修改變量就行了。這種方式改變 java 的啟動參數(shù)方式是這樣:

          export MAVEN_OPTS="-javaagent:$JacocoJarPath=includes=*,output=TCPserver,port=2014,address=192.168.110.1"

          這句命令加在哪里呢?就是 run 之前。為什么呢,因為這樣一改,你的所有的 mvn 命令都會生效,但其實我們只想介入啟動過程。因此,前面提到的兩套啟動命令,就可以改成如下方式:

          mvn clean install
          export MAVEN_OPTS="-javaagent:$JacocoJarPath=includes=*,output=TCPserver,port=2014,address=192.168.110.1"
          mvn tomcat7:run -Dport=xxx
          export MAVEN_OPTS=""

          mvn clean install
          export MAVEN_OPTS="-javaagent:$JacocoJarPath=includes=*,output=TCPserver,port=2014,address=192.168.110.1"
          mvn spring-boot:run -Dport=xxx
          export MAVEN_OPTS=""

          當(dāng)然,你的 run 命令,也可能是其他變種,比如:nohup mvn …. & 這種后臺啟動的方式,也是可以的。最后修改為 "" 是因為擔(dān)心對后續(xù)的 mvn 命令產(chǎn)生影響,其實如果你切換了 terminal 窗口,這個臨時變量就會失效,不會對環(huán)境造成污染。

          如果應(yīng)用啟動成功了,就可以按照前面的方式,netstat 叛別一下 TCP 服務(wù)是否真的啟動。

          如果你設(shè)置了這個變量的位置不對,那你用 mvn 命令的時候,可能會出現(xiàn)如下的異常:

          java.net.BindException: Address already in use: bind

          這時候,就需要去檢查一些,你配置的 Jacoco 端口是不是在啟動應(yīng)用服務(wù)時已經(jīng)被占用?;蛘吣闩R時設(shè)置了 MAVEN_OPTS 這個變量,啟動之后又沒有改回來,然后接著運行了 mvn 命令,這時候也會出現(xiàn)這種錯誤。這里請務(wù)必關(guān)注。

          提一句題外話,ANT 的方式是不是也可以通過臨時修改 ANT_OPTS 參數(shù)進行啟動 (因為 ANT 和 MAVEN 本是一家子嗎,我猜底層可能差異不是很大),我不曾做嘗試,有興趣的可以嘗試下。

          5.4 ANT 構(gòu)建,通過 XML 配置文件啟動

          這種方式可能實現(xiàn)啟動應(yīng)用的階段不同,但大都配置在 build.xml 里,這里請根據(jù)不同的項目做不同的適配。

          它的原理是,在 Ant 的啟動 target 中,有個 的標(biāo)簽,給她增加一個 jvmarg 參數(shù)的子標(biāo)簽,如下代碼:

          <jvmarg value=”-javaagent:$JacocoJarPath=includes=*,output=TCPserver,port=2014,address=192.168.110.1” />

          比如我們的啟動命令是這樣:

          ant -f build.xml clean  build  startJetty

          以此啟動之后,將會注入 Jacoco 的代理,最終可以按照上面的方式判斷端口是否啟動。

          5.5 java -jar 方式啟動

          這種最簡單直接:

          java -javaagent: $JacocoJarPath=includes=*,output=TCPserver,port=2014,address=192.168.110.1 -jar  xxxxxxxxxx.jar 

          注意,javaagent 參數(shù),一定要在 jar 包路徑之前,盡量在-jar 之前,不然可能不會生效。請注意 java -jar 命令的使用方式,在 jar 包前面?zhèn)鬟M去的是給 jvm 啟動參數(shù)的,在 jar 包之后跟的是給 main 方法的。

          啟動后,依然按照前面的方式判斷是否啟動了監(jiān)聽端口。

          5.6 啟動之后

          啟動之后,就進行測試就可以了,跟平常不注入 Jacoco 代理是無異的。

          想繼續(xù)觀看精彩內(nèi)容可看下文。

          (文章來源于霍格沃茲測試學(xué)院)

          于前端程序員來說,V8引擎無疑是最為熟悉的工具之一了。V8是Google開源的JavaScript和WebAssembly引擎,用C++編寫。它用于Chrome和Node.js等。V8可以獨立運行,也可以嵌入到任何C++應(yīng)用程序中。

          為了測試V8作為JavaScript引擎的性能,Google隨后也開發(fā)了一套V8基準(zhǔn)測試套件,在運行時,V8基準(zhǔn)套件會載入一些特定的JavaScript代碼,從而測試引擎的內(nèi)核、加密、解密、渲染等速度。而該套件也就成為了JavaScript引擎性能的標(biāo)準(zhǔn)。

          在該套件的第七個版本中,一共包括了八項基準(zhǔn)測試,最終得分為這八項測試得分的幾何平均數(shù)。得分越高表明速度越快。這八項測試的具體內(nèi)容如下:

          一、Richards基準(zhǔn)

          操作系統(tǒng)內(nèi)核的模擬基準(zhǔn), 最早出現(xiàn)于Matin Richards開發(fā)的BCPL中(539 行)。

          主要關(guān)注點:屬性加載/存儲、函數(shù)/方法調(diào)用

          次要關(guān)注點:代碼優(yōu)化、消除冗余代碼

          二、DeltaBlue基準(zhǔn)

          單向約束求解,最早出現(xiàn)于 John Maloney 和 Mario Wolczko開發(fā)的Smalltalk中 (880 行)。

          主要關(guān)注點:多態(tài)

          次要關(guān)注點:OO 樣式編程

          三、Crypto基準(zhǔn)

          Tom Wu開發(fā)的以代碼為基礎(chǔ)的加密解密基準(zhǔn)(1698 行)。

          主要關(guān)注點:位運算

          四、RayTrace基準(zhǔn)

          Adam Burmister開發(fā)的以代碼為基礎(chǔ)的光線追蹤基準(zhǔn) (904 行)。

          主要關(guān)注點:參數(shù)對象,應(yīng)用

          次要關(guān)注點:原型庫對象,創(chuàng)建模式

          五、EarleyBoyer基準(zhǔn)

          經(jīng)典Scheme 基準(zhǔn), 由Florian Loitsch的Scheme2Js編譯器翻譯為JavaScript (4684 行)。

          主要關(guān)注點:快速創(chuàng)建、銷毀對象

          次要關(guān)注點:閉包, 參數(shù)對象

          六、RegExp基準(zhǔn)

          正則表達式基準(zhǔn),從50多個最流行的網(wǎng)頁中提取正則表達式操作所產(chǎn)生的(1761 行)。

          關(guān)注點:正則表達式

          七、Splay基準(zhǔn)

          數(shù)據(jù)操作基準(zhǔn),處理伸展樹和執(zhí)行自動內(nèi)存管理子系統(tǒng) (394 行)。

          主要關(guān)注點:快速創(chuàng)建、銷毀對象

          八、NavierStokes基準(zhǔn)

          根據(jù)奧利弗·亨特的代碼,在2D上解決navierstokes方程,重操縱雙精度數(shù)組。(387 行).

          主要關(guān)注點:讀取和寫入數(shù)字?jǐn)?shù)組。

          次要關(guān)注點:浮點數(shù)學(xué)運算。

          V8基準(zhǔn)測試在早期的JavaScript引擎開發(fā)過程中應(yīng)用廣泛,很多JS引擎都使用該基準(zhǔn)測試用于評測其性能。常用的JS引擎測試結(jié)果如下:

          盡管V8基準(zhǔn)測試套件非常經(jīng)典,但是隨著技術(shù)的發(fā)展,Google又推出了新的基準(zhǔn)測試套件Octane 1.0和2.0,陸續(xù)增加了下列九項測試基準(zhǔn):

          pdf.js:在JavaScript中實現(xiàn)了Mozilla的PDF閱讀器。它可以測量解碼和解釋的時間(33,056行)。

          主要關(guān)注點:數(shù)組和類型化數(shù)組操作。

          次要關(guān)注點:數(shù)學(xué)運算和位運算,以及對未來語言功能(例如 promise)的支持

          SplayLatency:Splay 測試側(cè)重于虛擬機的垃圾回收子系統(tǒng)。SplayLatency 對現(xiàn)有 Splay 代碼進行頻繁測量檢查點插樁。檢查點之間長時間暫停表示 GC 延遲時間較長。此測試衡量延遲暫停的頻率,將它們分類為分桶,并根據(jù)低分懲罰頻繁地長暫停。

          主要關(guān)注點:垃圾回收延遲

          Mandreel:運行3D Bullet物理引擎,該引擎通過Mandreel將C++移植到JavaScript (277377行)。

          主要關(guān)注點:模擬

          MandreelLatency:與SplayLatency 測試類似,此測試通過頻繁的時間測量點對 Mandreel 基準(zhǔn)進行插樁。由于 Mandreel 對虛擬機編譯器施加壓力,因此該測試會提供編譯器引入的延遲指示。在測量點之間長時間暫停會降低最終得分。

          主要關(guān)注點:編譯器延遲時間

          GB Emulator:全部采用JavaScript模擬便攜式控制臺的架構(gòu),以及運行所需的3D模擬(11,097行)。

          主要關(guān)注點:模擬

          Code loading:測量Javascript引擎在加載了一段大型的Javascript程序后開始解碼的速度有多快,一個常見的實例為Social Widget。該測試的源代碼來自開源代碼庫(Closure, jQuery)(1,530行)。

          主要關(guān)注內(nèi)容:JavaScript 解析和編譯

          Box2DWeb:基于流行的2D物理引擎Box2DWeb,最初由Erin Catto編寫,現(xiàn)被移植到JavaScript。(560行,9000+ 精簡版)

          主要關(guān)注點:浮點數(shù)學(xué)運算。

          次要關(guān)注點:包含 Double 的屬性、訪問器屬性。

          Zlib:從 Mozilla Emscripten 套件執(zhí)行的 zlib asm.js/Emscripten 測試(在工作負(fù)載 1 中運行)。代碼包含在 eval() 中,它保證我們測量的運行時間包括在所有瀏覽器上解析和編譯(2,585 行)。

          主要關(guān)注點:代碼編譯和執(zhí)行

          Typescript:Microsoft&Type 39 TypeScript 編譯器是一款復(fù)雜的應(yīng)用。此測試用于衡量 TypeScript 編譯本身所需的時間,它代表虛擬機在處理復(fù)雜、可調(diào)整大小的 JavaScript 應(yīng)用(25918 行)方面的表現(xiàn)。

          主要關(guān)注點:運行復(fù)雜、繁重的應(yīng)用

          除此之外,常用的JavaScript基準(zhǔn)測試工具還有Mozilla發(fā)布的Kraken、蘋果的JetStream、以及Speedometer和Speed-Battle等。

          喜歡本文的話,歡迎關(guān)注活在信息時代哦:)


          主站蜘蛛池模板: 亚洲香蕉久久一区二区 | 一区二区视频在线| 国产成人久久一区二区三区| 亚洲老妈激情一区二区三区| 亚洲日韩国产一区二区三区在线 | 中文人妻av高清一区二区| 欧美日韩精品一区二区在线视频| 国产精品日本一区二区不卡视频 | 亚洲大尺度无码无码专线一区| 国产精品亚洲综合一区| 日本一区二区三区在线观看视频 | 中文字幕在线一区二区三区| 国产微拍精品一区二区| 国产成人精品第一区二区| 高清一区二区三区日本久| 激情综合一区二区三区| 亚洲片一区二区三区| 亚洲日本中文字幕一区二区三区| 在线免费视频一区二区| 国产午夜精品一区二区三区极品| 中文字幕AV一区二区三区人妻少妇| 亚洲成在人天堂一区二区| 日韩精品中文字幕无码一区 | 精品成人乱色一区二区| 亚洲AV无码一区二区三区系列| 国产一区二区三区在线观看精品| 国产成人片视频一区二区| 国产乱码精品一区二区三| 中文字幕人妻丝袜乱一区三区 | 亚洲色无码专区一区| 女同一区二区在线观看| 国产伦精品一区三区视频| 一区二区三区免费精品视频| 色婷婷AV一区二区三区浪潮 | 视频一区二区在线播放| 一区二区三区福利视频| 亚洲色欲一区二区三区在线观看| 亚洲V无码一区二区三区四区观看| 亚洲国产一区在线| 亚洲A∨精品一区二区三区下载| 在线观看国产一区二区三区|