微信开发工具特点_微信开发者工具怎么测试java微信开发 - CSDN
  • 在头像后边有三个按钮: ...编译模式:普通编译和自定义编译条件 预览:在真机预览 远程调试:真机的远程调试功能,会通过我们的网络连接对我们手机运行的小程序进行一个调试 切后台:切后台按钮会帮助我们快速的切...

    这里写图片描述
    个人中心:点击头像显示的是个人中心面板,展示的是小程序版本以及系统版本更新之后的一个推送消息,也方便我们去切换我们的小程序账号
    在头像后边有三个按钮:
    模拟器,编辑器和调试器:点击来显示或隐藏相应的模块
    编译模式:普通编译和自定义编译条件
    预览:在真机预览
    远程调试:真机的远程调试功能,会通过我们的网络连接对我们手机运行的小程序进行一个调试
    切后台:切后台按钮会帮助我们快速的切到不同的场景值,通过这个场景值可以帮助我们去个性化一些我们的功能需求
    清缓存:我们可以清楚我们开发者工具和我们调试设备的一个数据缓存,文件缓存,授权缓存,网络缓存和我们的登录状态
    上传,测试,腾讯云,详情
    上传会帮助我们把本次的小程序代码上传到我们的管理后台,会默认的设置为我们的开发版本
    小程序都有哪些版本?
    这里写图片描述
    预览版本:在手机上预览在我们手机上是一个怎样的表现
    开发版本:通过上传之后把我们的本地代码。上传成一个具有版本号的小程序的应用,那么应用开发者权限的成员可以通过小程序开发助手来看到我们的开发版本
    体验版本:就是我们在小程序管理后台可以直接将我们的开发版本切换成我们的体验版本,具有体验权限的成员就可以看到体验版本
    如果我们要将我们的开发版本上线成一个线上版本的话,我们需要先去提交审核,提交审核之后,我们的小程序就称为了一个审核版本的小程序,那么微信通过我们的审核之后,我们的小程序就正式的发布上线了。

    测试按钮:测试按钮我们可以通过每24小时生成一个测试报告。微信会给我们随机的分配4到8种的机型测试我们的小程序页面的一个首屏加载时间,CPU占比等这些指数
    腾讯云:第三方平台,可以快速的帮助我们构建一个小程序的开发环境和线上环境
    点击详情,会弹出一个详情的面板,可以通过一些项目的设置,还可以看到我们一些域名信息,腾讯云的状态
    项目设置:可以设置调试的一个基础库版本,
    可以设置编译的配置:Es6转ES5等等

    调试模块:
    主要分为七个模块
    这里写图片描述
    console: 打印小程序页面的调试log信息
    sources:会列出微信小程序页面的所有脚本文件
    Network:展示网络请求的状态信息
    Stroge:在小程序里面通过调用wx.setStroge和wx.setStrogeSycc函数设置我们的缓存的时候,在这里可以动态的修改这些缓存数据
    APPData: 是微信小程序页面上真实展示的一个数据,可以在这里动态的修改,来查看我们小程序页面在模拟器上不同设备的一个兼容性的情况
    wxml 页面:展示了微信小程序页面 的各个组件元素以及我们可以通过对这些组件元素。对它进行一个样式属性的修改
    sensor:只要是我们的一个地址位置信息和一个设备旋转角度的一个展示,在这里我们可以动态的去修改我们的地理位置信息来模拟我们小程序在不同地理位置下的一个表现,在设备旋转角度这里,我们可以设置旋转角度的参数来查看它的一个设备的旋转角度,可以看到各个坐标轴的变化

    OK,这就是对开发者工具详解。

    展开全文
  • 这里我记录一下自己使用微信开发工具的经验。(本文只讲述移动开发经验) 1.首先微信公众平台下载相应版本的微信开发工具。地址(微信公众平台文档)选择微信网页开发,选择下载就可以。 2.下载安装后的首页面...
       微信开发少不了,微信端的测试,但是基于手机调式特别困难,造成浪费大量的时间。这里我记录一下自己使用微信开发工具的经验。(本文只讲述移动开发经验)
    
    1.首先微信公众平台下载相应版本的微信开发工具。地址(微信公众平台文档)选择微信网页开发,选择下载就可以。
    2.下载安装后的首页面如下:

    选择1,2扫码登录即可。

    2、选择移动调式,普通调式。


     按照上述步骤连接成功之后,点击开始调式,就会出现实时请求,可以查看对应的参数以及响应。

    4、如下图


    5.选择x5调式


     按照上述步骤,点击开始调式,出现如下页面 

     第一次点击inspect 会出现空白页,这是你需要翻墙,翻墙成功后,就可以点击了出现和chrome调式页面。(注:翻墙工具,我用的是蓝灯,需要的话,可以给我留言)

    6、使用chrome devtool调式,

      1、首先在手机上将普通调式的代理关掉,选择无就行,然后使用usb连接手机,如何连接请自行百度。我这里讲一下我遇到的问题。

    打开chrome浏览器,输入chrome://inspect/#devices,出现offinline,标识设备没有连接。这是应该下载响应手机的驱动,可以到手机官网上下载,或者使用地方工具,例如腾讯管家,或者豌豆荚,会自动下载驱动,安装后就可以出现如下页面。


    7、欢迎大家多多批评指正!!!!!!

     

    展开全文
  • 微信开发最大的特点就是不好调试,所以微信官方退出了一款调试工具! 下载地址: 微信开发者工具项目演示 配置: 我这里是选择 ios 手机代理配置 打开手机选择网络(必须确保手机,电脑在同一局域网下面) 然后点击...

    微信开发最大的特点就是不好调试,所以微信官方推出了一款调试工具!

    下载地址:传送门

    微信开发者工具项目演示

    配置:

    我这里是选择 ios

    在这里插入图片描述

    手机代理配置

    打开手机选择网络(必须确保手机,电脑在同一局域网下面)

    在这里插入图片描述

    在这里插入图片描述

    然后点击微信调试
    出现下面连接结果界面:

    在这里插入图片描述

    然后用手机打开微信里面相应网页(你需要调试的功能页面,菜单或者页面)

    下面是我自己点击菜单后的页面,以及连接后的结果页面
    在这里插入图片描述

    展开全文
  • 相信做过微信小程序的都知道,官方给出的微信web开发工具上根本就无法加载node_modules包,即使可以加载,node_modules动辄几十M的大小,小程序的代码限制在1M以内,微信小程序的三个不足: 1无法调用npm包 2无法...

    相信做过微信小程序的都知道,官方给出的微信web开发工具上根本就无法加载node_modules包,即使可以加载,node_modules动辄几十M的大小,小程序的代码限制在1M以内,微信小程序的三个不足:

    1无法调用npm包

    2无法使用babel转吗

    3无法重用组件(像react那样重用组件功能)

    接下来给大家介绍一个相对完整的微信开发解决方案:

    Labrador:(目前最新版本为:0.6.12)

    github地址:https://github.com/maichong/labrador

    特点:

    1,使用Labrador框架可以使微信开发者工具支持加载海量NPM包

    2,支持ES6/7标准代码,使用async/await能够有效避免回调地狱

    3,组件重用,对微信小程序框架进行了二次封装,实现了组件重用和嵌套

    4,自动化测试,非常容易编写单元测试脚本,不经任何额外配置即可自动化测试

    5,使用Editor Config及ESLint标准化代码风格,方便团队协作

    当然了也有缺点,你看完会发现缺点

    首先系统全局安装nodejs和Labrador命令行工具。

    npm install -g labrador-cli

    查看当前labrador版本

    labrador -V

    新建一个目录,初始化项目

    labrador create mylabrador        # 初始化labrador项目 mylabrador是你的项目名字


    用Egret Wing3(这个IDE更适合开发微信小程序),打开labradordemo这个项目,

    开启代码自动转换功能

    labrador watch

    然后用微信开发着工具打开labradordemo项目下面的dist文件


    这个里面不需要做任何的编码工作,在下面的src目录作修改,会自动同步到微信开发者工具上面


    在src/pages/index新增一个index.json文件,主要内容为设置页面的title

    {
      "navigationBarTitleText": "主页",
      "enablePullDownRefresh": false
    }

    然后保存,会同步到微信开发者工具


    labrador 库对全局的 wx 变量进行了封装,将所有wx 对象中的异步方法进行了Promise支持, 除了同步的方法,这些方法往往以on*create*stop*pause*close* 开头或以 *Sync 结尾。在如下代码中使用 labrador 库。


    import wx, { Component, PropTypes }from'labrador';


    wx.wx;          // 原始的全局 wx 对象

    wx.app;         // 和全局的 getApp() 函数效果一样,代码风格不建议粗暴地访问全局对象和方法

    wx.currentPages // 对全局函数 getCurrentPages() 优雅的封装

    Component;      // Labrador 自定义组件基类

    PropTypes;      // Labrador 数据类型校验器集合


    wx.login;       // 封装后的微信登录接口

    wx.getStorage;  // 封装后的读取缓存接口

    //... 更多请参见 https://mp.weixin.qq.com/debug/wxadoc/dev/api/


    我们建议不要再使用 wx.getStorageSync() 等同步阻塞方法,而在async 函数中使用await wx.getStorage() 异步非阻塞方法提高性能,除非遇到特殊情况。



    app.js文件

    import request from 'al-request';
    import { setStore } from 'labrador-redux';
    import { sleep } from './utils/utils';
    import store from './redux';


    if (__DEV__) {
      console.log('当前为开发环境');
    }


    // 向labrador-redux注册store
    setStore(store);


    export default class {
      async onLaunch() {
        try {
          await sleep(100);
          await request('api/start');
        } catch (error) {
          console.error(error);
        }
        this.timer();
      }


      async timer() {
        while (true) {
          console.log('hello');
          await sleep(10000);
        }
      }
    }

    代码中全部使用ES6/7标准语法。代码不必声明 use strict ,因为在编译时,所有代码都会强制使用严格模式。

    代码中并未调用全局的 App() 方法,而是使用export 语法默认导出了一个类,在编译后,Labrador会自动增加App() 方法调用,所有请勿手动调用 App() 方法。这样做是因为代码风格不建议粗暴地访问全局对象和方法。


    Labrador的自定义组件,是基于微信小程序框架的组件之上,进一步自定义组合,拥有逻辑处理、布局和样式。

    项目中通用自定义组件存放在src/compontents 目录,一个组件一般由三个文件组成,*.js*.xml*.less 分别对应微信小程序框架的jswxmlwxss 文件。在Labardor项目源码中,我们特意采用了xml less 后缀以示区别。如果组件包含单元测试,那么在组件目录下会存在一个*.test.js 的测试脚本文件。

    0.6 版本后,支持*.sass*.scss 格式样式文件。


    自定义组件示例

    下面是一个简单的自定义组件代码实例:


    逻辑 src/compontents/todo/todo.js


    import { Component, PropTypes } from 'labrador-immutable';


    const { string, bool, func } = PropTypes;


    class Todo extends Component {
      static propTypes = {
        id: string,
        title: string,
        createdAt: string,
        finished: bool,
        finishedAt: string,
        onRemove: func,
        onRestore: func,
        onFinish: func
      };


      constructor(props) {
        super(props);
        this.state = {
          icon: props.finished ? 'success_circle' : 'circle',
          className: props.finished ? 'todo-finished' : ''
        };
      }


      onUpdate(props) {
        this.setState({
          icon: props.finished ? 'success_circle' : 'circle',
          className: props.finished ? 'todo-finished' : ''
        });
      }


      handleRemove() {
        this.props.onRemove(this.props.id);
      }


      handleFinish() {
        if (this.props.finished) {
          this.props.onRestore(this.props.id);
        } else {
          this.props.onFinish(this.props.id);
        }
      }
    }


    export default Todo;

    自定义组件的逻辑代码和微信框架中的page很相似,最大的区别是在js逻辑代码中,没有调用全局的 Page() 函数声明页面,而是用 export 语法导出了一个默认的类,这个类必须继承于Component 组件基类。

    相对于微信框架中的page,Labrador自定义组件扩展了 propTypesdefaultPropsonUpdate()setState()children() 等方法和属性,children()方法返回当前组件中的子组件集合,此选项将在下文中叙述。

    Labrador的目标是构建一个可以重用、嵌套的自定义组件方案,在现实情况中,当多个组件互相嵌套组合,就一定会遇到父子组件件的数据和消息传递。因为所有的组件都实现了setState 方法,所以我们可以使用this._children.foobar.setState(data)this.parent.setState(data) 这样的代码调用来解决父子组件间的数据传递问题,但是,如果项目中出现大量这样的代码,那么数据流将变得非常混乱。

    我们借鉴了 React.js 的思想,为组件增加了 props 机制。子组件通过 this.props 得到父组件给自己传达的参数数据。父组件怎样将数据传递给子组件,我们下文中叙述。

    onUpdate 生命周期函数是当组件的 props 发生变化后被调用,类似React.js中的 componentWillReceiveProps 所以我们可以在此函数体内监测props 的变化。

    组件定义时的 propTypes 静态属性是对当前组件的props参数数据类型的定义。defaultProps 选项代表的是当前组件默认的各项参数值。propTypesdefaultProps 选项都可以省略,但是强烈建议定义 propTypes,因为这样可以使得代码更清晰易懂,另外还可以通过Labrador自动检测props值类型,以减少BUG。为优化性能,只有在开发环境下才会自动检测props值类型。

    编译时默认是开发环境,当编译时候采用 -m 参数才会是生产模式,在代码中任何地方都可以使用魔术变量__DEV__ 来判断是否是开发环境。

    组件向模板传值需要调用 setState 方法,换言之,组件模板能够读取到当前组件的所有内部状态数据。

    0.6版本后,Component 基类中撤销了setData 方法,新增了setState 方法,这样做并不是仅仅为了像React.js,而是在老版本中,我们将所有组件树的内部状态数据和props全存放在page.data中,在组件更新时产生了大量的setData 递归调用,为了优化性能,必须将组件树的状态和page.data 进行了分离。


    布局 src/compontents/todo/todo.xml


    <view class="list-item flex-row items-center todo {{state.className}}">
      <icon class="todo-icon" type="{{state.icon}}" size="20" color="#999" catchtap="handleFinish"/>
      <view class="block flex todo-title {{state.className}}-title"> {{props.title}} </view>
      <view class="btn btn-small {{props.finished?'btn-gray-hollow':'btn-danger'}}" catchtap="handleRemove">删除</view>
    </view>

    XML布局文件和微信WXML文件语法完全一致,只是扩充了两个自定义标签 <component/><list/>,下文中详细叙述。

    使用 {{}} 绑定变量时,以props.*state.* 开头,即XML模板文件能够访问组件对象的propsstate


    样式 src/compontents/todo/todo.less

    @import 'al-ui';


    .todo {
      background: #fff;
      font-size: @font-size-medium;
    }


    .todo-icon {
      margin-right: 10px;
    }


    .todo-finished {
      background: @color-page;
    }


    .todo-finished-title {
      .gray;
      text-decoration: line-through;
    }

    虽然我们采用了LESS文件,但是由于微信小程序框架的限制,不能使用LESS的层级选择及嵌套语法。但是我们可以使用LESS的变量、mixin、函数等功能方便开发。


    页面

    我们要求所有的页面必须存放在 pages 目录中,每个页面的子目录中的文件格式和自定义组件一致,只是可以多出一个*.json 配置文件。


    页面示例

    下面是默认首页的示例代码:


    逻辑 src/pages/index/index.js


    import wx, { Component, PropTypes } from 'labrador-immutable';
    import { bindActionCreators } from 'redux';
    import { connect } from 'labrador-redux';
    import Todo from '../../components/todo/todo';
    import * as todoActions from '../../redux/todos';
    import { sleep } from '../../utils/utils';


    const { array, func } = PropTypes;


    class Index extends Component {
      static propTypes = {
        todos: array,
        removeTodo: func,
        restoreTodo: func,
        createTodo: func,
        finishTodo: func
      };


      state = {
        titleInput: '',
        finished: 0
      };


      children() {
        let todos = this.props.todos || [];
        let unfinished = [];
        let finished = [];
        if (todos.length) {
          unfinished = todos.filter((todo) => !todo.finished);
          finished = todos.asMutable()
            .filter((todo) => todo.finished)
            .sort((a, b) => (a.finishedAt < b.finishedAt ? 1 : -1))
            .slice(0, 3);
        }
        return {
          list: unfinished.map((todo) => ({
            component: Todo,
            key: todo.id,
            props: {
              ...todo,
              onRemove: this.handleRemove,
              onRestore: this.handleRestore,
              onFinish: this.handleFinish
            }
          })),
          finished: finished.map((todo) => ({
            component: Todo,
            key: todo.id,
            props: {
              ...todo,
              onRemove: this.handleRemove,
              onRestore: this.handleRestore,
              onFinish: this.handleFinish
            }
          }))
        };
      }


      onUpdate(props) {
        let nextState = {
          finished: 0
        };
        props.todos.forEach((todo) => {
          if (todo.finished) {
            nextState.finished += 1;
          }
        });
        this.setState(nextState);
      }


      async onPullDownRefresh() {
        await sleep(1000);
        wx.showToast({ title: '刷新成功' });
        wx.stopPullDownRefresh();
      }


      handleCreate() {
        let title = this.state.titleInput;
        if (!title) {
          wx.showToast({ title: '请输入任务' });
          return;
        }
        this.props.createTodo({ title });
        this.setState({ titleInput: '' });
      }


      handleInput(e) {
        this.setState({ titleInput: e.detail.value });
      }


      handleRemove = (id) => {
        this.props.removeTodo(id);
      };


      handleFinish = (id) => {
        this.props.finishTodo(id);
      };


      handleRestore = (id) => {
        this.props.restoreTodo(id);
      };


      handleShowFinished() {
        wx.navigateTo({ url: 'finished' });
      }


      handleShowUI() {
        wx.navigateTo({ url: '/pages/ui/index' });
      }
    }


    export default connect(
      ({ todos }) => ({ todos }),
      (dispatch) => bindActionCreators({
        createTodo: todoActions.create,
        removeTodo: todoActions.remove,
        finishTodo: todoActions.finish,
        restoreTodo: todoActions.restore,
      }, dispatch)
    )(Index);


    页面代码的格式和自定义组件的格式一模一样,我们的思想是 页面也是组件

    js逻辑代码中同样使用 export default 语句导出了一个默认类,也不能手动调用Page() 方法,因为在编译后,pages 目录下的所有js文件全部会自动调用Page() 方法声明页面。

    我们看到组件类中,有一个对象方法 children() ,这个方法返回了该组件依赖、包含的其他自定义组件,在上面的代码中页面包含了三个自定义组件listtitlecounter ,这个三个自定义组件的key 分别为listmottocounter

    children() 返回的每个组件的定义都包含两个属性,component 属性定义了组件类,props 属性定义了父组件向子组件传入的props 属性对象。

    页面也是组件,所有的组件都拥有一样的生命周期函数onLoad, onReady, onShow, onHide, onUnload,onUpdate 以及setState函数。

    componetspages 两个目录的区别在于,componets 中存放的组件能够被智能加载、重用,pages 目录中的组件在编译时自动加上 Page() 调用,所以,pages 目录中的组件不能被其他组件调用,否则将出现多次调用Page()的错误。如果某个组件需要重用,请存放在componets 目录或打包成NPM包。


    注意 虽然页面也是组件,虽然页面的代码格式和组件一模一样,但是运行时,getCurrentPages() 得到的页面对象page 并非pages目录中声明的页面对象,page.root 才是pages目录中声明的页面对象,才是组件树的最顶端。这里我们用了组合 模式而非继承模式。

    注意 所有组件的生命周期函数支持 async ,但默认是普通函数,如果函数体内没有异步操作,我们建议采用普通函数,因为async 函数会有一定的性能开销,并且无法保证执行顺序。当声明周期函数内需要异步操作,并且【不关心】各个生命周期函数的执行顺序时,可以采用async 函数。



    布局 src/pages/index/index.xml


    <view class="todo-list has-toolbar">
      <view class="list">
        <list key="list" name="todo"/>
      </view>
      <block wx:if="{{state.finished}}">
        <view class="group-header">已完成</view>
        <view class="list">
          <list key="finished" name="todo"/>
        </view>
        <view wx:if="{{state.finished>3}}" class="padding-h-xxlarge padding-top-large">
          <view class="btn btn-gray-hollow block" catchtap="handleShowFinished">查看全部已完成</view>
        </view>
      </block>
      <view wx:if="{{props.todos.length}}" class="gray padding text-right">总数 {{props.todos.length}} 已完成
        {{state.finished}}
      </view>
      <view wx:else class="msg">
        <icon class="msg-icon" type="info" size="80" color="#ccc"/>
        <view class="msg-title">当前没有任务</view>
        <view class="msg-desc">请在下方输入框中填入新任务然后点击新增</view>
      </view>
      <view class="toolbar toolbar-bottom padding-h-xsmall">
        <view class="form-group flex">
          <input class="form-control" type="text" placeholder="请输入新的任务" value="{{state.titleInput}}"
                 bindinput="handleInput"/>
        </view>
        <view class="btn btn-success btn-toolbar" catchtap="handleCreate">新增</view>
      </view>
      <view class="footer">
        <view>Powered by Labrador</view>
        <text class="link" catchtap="handleShowUI">AL UI</text>
      </view>
    </view>

    XML布局代码中,使用了Labrador提供的 <component/> 标签,此标签的作用是导入一个自定义子组件的布局文件,标签有两个属性,分别为key (必选)和name (可选,默认为key的值)。key 与js逻辑代码中的组件key 对应,name 是组件的目录名。key 用来绑定组件JS逻辑对象的children 中对应的数据, name 用于在src/componetsnode_modules 目录中寻找子组件模板。


    样式 src/pages/index/index.less


    @import 'al-ui';
    @import 'todo';


    .todo-list {
      
    }


    LESS样式文件中,我们使用了 @import 语句加载所有子组件样式,这里的@import 'list' 语句按照LESS的语法,会首先寻找当前目录src/pages/index/ 中的 list.less 文件,如果找不到就会按照Labrador的规则智能地尝试寻找src/componetsnode_modules 目录中的组件样式。

    接下来,我们定义了 .motto-title-text 样式,这样做是因为motto key 代表的title组件的模板中(src/compontents/title/title.xml)有一个view 属于title-text 类,编译时,Labrador将自动为其增加一个前缀motto- ,所以编译后这个view所属的类为title-text motto-title-text (可以查看dist/pages/index/index.xml)。那么我们就可以在父组件的样式代码中使用.motto-title-text 来重新定义子组件的样式。

    Labrador支持多层组件嵌套,在上述的实例中,index 包含子组件listtitlelist 包含子组件title,所以在最终显示时,index 页面上回显示两个title 组件。


    自定义组件列表


    逻辑 src/components/list/list.js

    import wx, { Component } from 'labrador';

    import Title from'../title/title';

    import Item from'../item/item';

    import { sleep } from'../../utils/util';


    export defaultclassListextendsComponent {


      constructor(props){

        super(props);

        this.state= {

          items: [

            { id:1, title:'Labrador' },

            { id:2, title:'Alaska' }

          ]

        };

      }


      children (){

        return {

          title:{

            component: Title,

            props: { text:'The List Title' }

          },

          listItems:this.state.items.map((item)=> {

            return {

              component: Item,

              key: item.id,

              props: {

                item: item,

                title: item.title,

                isNew: item.isNew,

                onChange: (title)=> {this.handleChange(item, title) }

              }

            };

          })

        };

      }


      asynconLoad() {

        awaitsleep(1000);

        this.setState({

          items: [{ id:3, title:'Collie', isNew:true }].concat(this.data.items)

        });

      }


      handleChange(item, title) {

        let items=this.state.items.map((i)=> {

          if(item.id== i.id){

            returnObject.assign({},i,{ title });

          }

          return i;

        });

        this.setState({ items });

      }

    }

    在上边代码中的 children() 返回的listItems 子组件定义时,是一个组件数组。数组的每一项都是一个子组件的定义,并且需要指定每一项的key 属性,key 属性将用于模板渲染性能优化,建议将唯一且不易变化的值设置为子组件的key,比如上边例子中的id


    模板 src/components/list/list.xml

    <viewclass="list">

      <componentkey="title"name="title"/>

      <listkey="listItems"name="item"/>

    </view>

    在XML模板中,调用 <list/> 标签即可自动渲染子组件列表。和<component/> 标签类似,<list/> 同样也有两个属性,keyname。Labrador编译后,会自动将 <list/> 标签编译成wx:for 循环。


    自动化测试

    我们规定项目中所有后缀为 *.test.js 的文件为测试脚本文件。每一个测试脚本文件对应一个待测试的JS模块文件。例如src/utils/util.jssrc/utils/utils.test.js 。这样,项目中所有模块和其测试文件就全部存放在一起,方便查找和模块划分。这样规划主要是受到了GO语言的启发,也符合微信小程序一贯的目录结构风格。

    在编译时,加上 -t 参数即可自动调用测试脚本完成项目测试,如果不加-t 参数,则所有测试脚本不会被编译到dist 目录,所以不必担心项目会肥胖。


    普通JS模块测试

    测试脚本中使用 export 语句导出多个名称以test* 开头的函数,这些函数在运行后会被逐个调用完成测试。如果test测试函数在运行时抛出异常,则视为测试失败,例如代码:

    // src/util.js

    // 普通项目模块文件中的代码片段,导出了一个通用的add函数

    export functionadd(a, b) {

      return a+ b;

    }

    // src/util.test.js

    // 测试脚本文件代码片段


    import assert from'assert';


    //测试 util.add() 函数

    export functiontestAdd(exports) {

      assert(exports.add(1,1)===2);

    }

    代码中 testAdd 即为一个test测试函数,专门用来测试add() 函数,在test函数执行时,会将目标模块作为参数传进来,即会将util.js 中的exports 传进来。


    自定义组件测试

    自定义组件的测试脚本中可以导出两类测试函数。第三类和普通测试脚本一样,也为 test* 函数,但是参数不是exports 而是运行中的、实例化后的组件对象。那么我们就可以在test函数中调用组件的方法或则访问组件的propsstate 属性,来测试行为。另外,普通模块测试脚本是启动后就开始逐个运行test* 函数,而组件测试脚本是当组件onReady 以后才会开始测试。

    自定义组件的第二类测试函数是以 on* 开头,和组件的生命周期函数名称一模一样,这一类测试函数不是等到组件onReady 以后开始运行,而是当组件生命周期函数运行时被触发。函数接收两个参数,第一个为组件的对象引用,第二个为run 函数。比如某个组件有一个onLoad 测试函数,那么当组件将要运行onLoad 生命周期函数时,先触发onLoad 测试函数,在测试函数内部调用run() 函数,继续执行组件的生命周期函数,run() 函数返回的数据就是生命周期函数返回的数据,如果返回的是Promise,则代表生命周期函数是一个异步函数,测试函数也可以写为async 异步函数,等待生命周期函数结束。这样我们就可以获取run()前后两个状态数据,最后对比,来测试生命周期函数的运行是否正确。

    第三类测试函数与生命周期测试函数类似,是以 handle* 开头,用以测试事件处理函数是否正确,是在对应事件发生时运行测试。例如:

    // src/components/counter/counter.test.js


    export functionhandleTap(c, run) {

      let num= c.data.num;

      run();

      let step= c.data.num- num;

      if (step!==1) {

        thrownewError('计数器点击一次应该自增1,但是自增了'+ step);

      }

    }

    生命周期测试函数和事件测试函数只会执行一次,自动化测试的结果将会输出到Console控制台。


    项目配置文件

    labrador create 命令在初始化项目时,会在项目根目录中创建一个.labrador 项目配置文件,如果你的项目是使用 labrador-cli 0.3 版本创建的,可以手动增加此文件。

    配置文件为JSON5格式,默认配置为:

    {

      "define":{

        "API_ROOT":"http://localhost:5000/"

      },

      "npmMap":{

        "lodash-es":"lodash"

      },

      "uglify":{

        "mangle": [],

        "compress": {

          "warnings":false

        }

      },

      "classNames": {

        "text-red":true

      },

      "env":{

        "development": {},

        "production": {

          "define":{

            "API_ROOT":"https://your.online.domain/"

          }

        }

      }

    }


    展开全文
  • 微信开发的概念

    2019-12-03 23:23:16
    微信开发的概念 什么是微信开发 微信这个软件,提供了聊天、支付、分享、收藏等各种功能,同时用户基数庞大; 微信对外开放了很多接口和能力,程序员基于这些功能进行的二次开发,叫做微信开发 微信开放平台 微信...
  • 企业微信是腾讯推出的一个新的办公协作平台,通过与微信一致的沟通体验,为企业员工提供最基础和最实用的...本文以该项目为例对在企业微信平台开发企业应用的特点进行了总结,重点分析了企业微信开发平台对应用开发...
  • 本文主要记录一下初次开发小程序一些注意事项,小程序开发语言,对小程序的审核要求,小程序的特点开发特点,后面会再写下是否有三方好用的工具,及开发中遇到的js,html,css 相关的问题及解决方法。毕竟借小程序写...
  • 记得在两个月前,我在微信官方开发群里问个人公众帐号与企业公众帐号有什么区别的时候,还被人笑话过,没有人愿意告知,也许是这个问题问的太过于简单了吧。我想一定也还有不少朋友在刚接触时,也搞不清楚这一点。...
  • C#微信开发

    2017-12-24 10:35:37
    C#开发微信门户及应用教程   作者:伍华聪   C#开发微信门户及应用(1)--开始使用微信接口 6 1、微信账号 6 2、微信菜单定义 7 3、接入微信的链接处理 8 4、使用开发方式创建菜单 14 5、我创建的菜单案例 17 C#...
  • HTML我帮您打造微信小程序web可视化开发者工具是一款的可视化Web...高效、稳定和可扩展的特点,使微信小程序的开发更快捷和简单。 源码只需要20000元。 HTML我帮您打造微信小程序web可视化开发者工具为企业提
  • 概述 微信公众号开发,其实就是微信使用者、微信公众号平台和自身服务器的http消息交互;在这一系列过程中,微信公众号平台充当了...图1 微信公众号开发消息交互 微信公众号开发有官方文档,官方文档地址:https:/...
  • 文章目录微信小程序开发一 概述1.1 什么是微信小程序1.2特点及优势二 开发准备 微信小程序开发 一 概述 1.1 什么是微信小程序 小程序是一种新的开放能力,开发者可以快速地开发一个小程序。小程序可以在微信内被...
  • 微信公众号开发技术要点 微信公众号开发技术要点 微信公众号及其接口功能介绍 基本概念 公众号开发者模式 代码验证及图示 Open ID与Union ID 基本概念 使用说明 Access_token 基本介绍 注意事项 获取流程 ...
  • 摘要:本文介绍了微信小程序在今年发展的来龙去脉,介绍了微信小程序在微信中的基础特性和用法,为开发做好准备。1. 微信小程序的介绍好不容易毕业拿到学位证书了,在九月入学研究生之前原本以为可以休息一下,结果...
  • 微信开发文档 https://mp.weixin.qq.com/wiki 普通商户版 和 服务商版:微信代理商 具体而言,网页授权流程分为四步: 0、设置域名(需要二级域名) 需要内网穿透工具,将本地网络映射到公网 http://natapp.cn ...
  • 微信公众号开发实例

    2017-08-24 14:17:37
    微信公众号开发实例目录 1.简介 2 1.1 基础知识 2 2.开发准备 5 2.1 业务流程 5 2.2 微信公众号 5 2.3 WEB服务器 8 2.4 通信协议 13 2.5 开发框架 19 2.6 小结 20 3.开发实例 21 3.1 业务流程 21 3.2 ...
  • 微信小程序开发功能特点3.小程序开发流程3.1 微信公众平台注册3.2 微信开发者工具下载3.3 微信开发者工具界面上的基本功能介绍 1.什么叫做微信小程序 微信小程序(Wechat Mini Program)简称小程序,英文名Mini ...
  • 微信小程序特点

    2016-11-14 13:53:30
    微信小程序有以下几个特点 微信小程序的易上手 微信小程序的门槛低 微信小程序的社交性 微信小程序的渠道性 通过以上几个特点,探讨下微信小程序会给哪些人带来机会? 适合创业者-可能是最好的...
1 2 3 4 5 ... 20
收藏数 22,739
精华内容 9,095
关键字:

微信开发工具特点