手の取っ手はゼロから小さいプログラムのユニットのテストを始めます(避難所の指針とソースの追跡を付け加えます).


ユニットテストはありふれた話題です.Web/NodeJs環境に基づくテストフレームワーク、テスト教程は数え切れないほど多く、成熟してきました.しかし、WeChatアプレットのユニットテストについては、まだ初歩的な状態です.この二日間はWeChatアプレットのテストを研究しています.また、いくつかのピットにも遭遇しました.ここで記録してください.本文を見ている仲間に少しの助けを与えたいです.回り道を少なくしてください.
この文章は内容が多いですが、干物がいっぱいで、よく分からない仲間は公衆番号を見てメッセージをくれます.
demoアドレス
https://github.com/xialeistudio/miniprogram-unit-test-demo
キー依存バージョン
本文の作成時の依存バージョンは以下の通りです.
  • miniprogram-simulate:1.0.7
  • j-component:1.1.6
  • miniprogram-exparser:0.0.6
  • テストの流れ
  • は、アプレットプロジェクトを初期化し、テスト待ちコンポーネント
  • を作成する.
  • Just,miniprogram-simulate試験環境
  • をインストールします.
  • 試験用例を作成する
  • 試験を実行します.
    初期化ウィジェット項目
  • は、ウィジェット開発ツールを使用して、新しいプロジェクトを初期化し、APPID を選択すればいい.言語選択Javascript.
  • ウィジェット開発ツールを使って/components/userコンポーネント
  • を新規作成します.
  • components/user.js
    // components/user.js
    Component({
        data: {
            nickname: ''
        },
        methods: {
            handleUserInfo: function(e) {
                this.setData({ nickname: e.detail.userInfo.nickName })
            }
        }
    })
  • components/user.wxml
     {{nickname}}
     
  • pages/index/index.js
    Page({
        data:{}
    })
  • pages/index/index.wxml
    
        
    
  • ウィジェット開発ツールを開くと、Oauthボタンが表示され、クリックしたらニックネームが表示されます.
  • により、試験用例
  • が得られる.
    just/miniprogram-simulteをインストールして環境をテストします.
  • JSプロジェクトのウィジェットルートディレクトリにpackage.jsonがないので、手動で
  • を生成する必要があります.
  • は端末を開け、プロジェクトルートディレクトリ実行npm init -ypackage.json
  • を生成する.
  • 試験工具セットnpm install jest miniprogram-simulate --save-dev
  • をインストールします.
  • package.jsonを編集し、scriptstestコマンド
    {
        "name": "unit-test-demo",
        "version": "1.0.0",
        "description": "",
        "main": "app.js",
        "scripts": {
            "test": "jest"
        },
        "keywords": [],
        "author": "",
        "license": "ISC",
        "devDependencies": {
            "jest": "^24.8.0",
            "miniprogram-simulate": "^1.0.7"
        }
    }
  • を新設する.
    試験用例の作成
  • プロジェクトルートディレクトリにtests/components/user.spec.jsファイルを新規作成する(ディレクトリは手動で作成する必要がある)
  • コードは以下の通りです.
    テストを実行
  • npm run test、一秒後に発見されました.
  • 部分エラーログ:
    const simulate = require('miniprogram-simulate');
    const path = require('path');
    
    test('components/user', (done) => { //       ,  done           ,         jest,       
    const id = simulate.load(path.join(__dirname, '../../components/user')); //     
    const component = simulate.render(id); //     
    
    const text = component.querySelector('.nickname'); //   nickname  
    const button = component.querySelector('.button'); //   button  
    button.dispatchEvent('getuserinfo', { //       
        detail: {   //       
            userInfo: {
                nickName: 'hello',
            },
        },
    });
    setTimeout(() => { //     
        expect(text.dom.innerHTML).toBe('hello'); //   text   innerHTML           
        done();
    }, 1000);
    });
  • 原因を推測できます.
  • dispatch Eventのイベントトリガに問題があり、handleUserInfoがトリガされていない[1]
  • dispatch Eventのイベントトリガに成功しましたが、トリガパラメータに問題があります.
  • エラー分析(ソース追跡プロセス)
  • 第1の原因について、テストコードを書いてもいいです.
    Expected: "hello"
    Received: ""
         at toBe (/Users/xialeistudio/WeChatProjects/unit-test-demo/tests/components/user.spec.js:18:32)
         at Timeout.callback [as _onTimeout] (/Users/xialeistudio/WeChatProjects/unit-test-demo/node_modules/jsdom/lib/jsdom/browser/Window.js:678:19)
         at listOnTimeout (internal/timers.js:535:17)
         at processTimers (internal/timers.js:479:7)
  • components/user.js、イベントはまだ成功のトリガを見ることができますが、npm run testdetail
     Component({
         data: {
             nickname: ''
         },
         methods: {
             handleUserInfo: function(e) {
                 console.log(e);
             }
         }
     })
  • です.
  • 原因の1は排除して、原因の2
  • を調べます.
  • {}方法はdispatchEventであり、 関数で
  • に戻る.
  • simulate.renderをブラウズし、node_modules/miniprogram-simulate/src/index.jsを見て、戻ってくるコンポーネントがrender (152 )によって
  • を提供することが見える.
  • ブラウズjComponent.createnode_modules/j-component/src/index.js関数は、createの例に戻り、RootComponentRootComponentによって提供される
  • であることがわかる.
  • ブラウズ./render/component.jsnode_modules/j-component/src/render/component.js関数は、ここでログテストを行うことができます(ここではしません.結果はここのoptionsはdispatchEvent user.spec.js関数のdispatchEventで、 は値があります)
  • ソースコードを追跡し続けています.detailですから、 のコードブロックに行きます.
  • は、91 の関数を呼び出したことを見ることができます.exparser.Event.dispatchEventを呼び出して、カスタムイベントを包装しました.ここでは一番下の階にはまだ来ていません.
  • を追跡し続ける必要があります.
  • オブジェクトはexparser.Event.createから提供されたもので、exparserを参照すると、このファイルが混同されていることが分かりましたが、大丈夫です.
  • webstormを使ってこのファイルをフォーマットしました.ここでgithub wxparser.jsまでフォーマットしました.オンラインで
  • を見ることができます.
  • は、ソースコードの中でminiprogram-exparser node_modules/miniprogram-exparser/exparser.min.js関数を検索する必要があります( , , )、忍耐力が必要です.
  • のこの割当値を見ることができ、createObject.create s.detail = tであり、tcreateで入力されたが、 に入力されたので、node_modules/j-component/render/component.jsを取得したときwxparser.Event.createで、 {}に修正すればよく、修正後のコードは以下の通りである.
  • 再試験
      console.log components/user.js:21
     { type: 'getuserinfo',
       timeStamp: 948,
       target: { id: '', offsetLeft: 0, offsetTop: 0, dataset: {} },
       currentTarget: { id: '', offsetLeft: 0, offsetTop: 0, dataset: {} },
       detail: {},
       touches: {},
       changedTouches: {} }
  • ピットガイド
  • detailはHTMLと同じ使い方をしていますが、 {}ではなくoptions.detail||{}で実行する必要があります.HTMLではquerySelectorで実行される
  • です.
  • はトリガイベントであり、 .domが実行する必要があり、上記コードはトリガDOMNodedispatchEvent
  • である.
  • イベント名規範:button 、例コード 、トリガ時dispatchEvent、もし bind であれば、トリガ時はbindgetuserinfoです.
  • getuserinfoの下の階はbindtapこのtapで、追跡のソースコードの発見は実行が非同期です(コードファイルdispatchEvent、関数名j-component)
    //      
      const customEvent = new CustomEvent(eventName, options);
    
      //       
      setTimeout(() => {
        dom.dispatchEvent(customEvent);
    
        exparser.Event.dispatchEvent(customEvent.target, exparser.Event.create(eventName, {}, {
          originalEvent: customEvent,
          bubbles: true,
          capturePhase: true,
          composed: true,
          extraFields: {
            touches: options.touches || {},
            changedTouches: options.changedTouches || {},
          },
        }));
      }, 0);
  • は、npm の存在により、イベントが非同期であることをトリガするため、断言を書く際にタイマー
  • を追加する必要がある.
    おわりに
    基本的には経験が豊富ではありませんが、公式サイトから提供されたツールとnode_modules/j-component/src/render/component.jsに基づいて、問題が発生した時によくチェックして修正しても問題が解決できます.ユニットテストに疑問がある仲間はコードをスキャンして交流してもいいです.