起因

上周老板又给了我这个车辆工程毕业的码农一份工作:

要我写一个测试台架出来。

我先简单的分析了测试台架的几种典型的工况:

1、发送一个CAN信号,测试能否查到。

2、发送一个信号,是否能在规定时间内得到相应的回复

测试用例可能有上千条,但是万变不离其宗,总而言之就是测试信号和一些功能是否正常,暂时不涉及节点的模拟和管理等。

最后我采用.Net框架方便调用DLL(因为有很多硬件要对接),使用JS引擎实现测试的基础功能,使用JSON序列化数据。

Winform+WPF控件实现界面,使用Python将已有的测试用例转换成代码。

最后,实现了测试自动化的同时,允许测试人员对已有的用例进行修改,做到修改用例不用重新编译代码,开发和调试方便。

思考

那么我其实可以通过统一测试用例配置文件格式的方式来做:

例如:

TX(ID=123,Data=[1,2,3,4,5,6,7,8])

WaitForRX(ID=124,Data[3]=0,timeout=5000ms)

或者是

{"TX",123,[1,2,3,4,5,6,7,8]}

{"RX",5000,124,[?,?,?,0,?,?,?,?]}

这种JSON格式的测试用例。最后提供一套测试用例的编辑、转换器,测试的同志就可以开心的使用了。

但是,测试用例里又出现了这一种:

While sending Signal XX in 50 Frame/Second, XXXXXXX

这个时候我决心把常用的API暴露出来,形成一种新的语言,我们不妨称之为CAN控制语言,于是诞生了CAPL,我们给CAPL写了个IDE叫CANOE,成立了Vector公司,现在……

咳咳,扯淡扯远了!

我只是简单的把CAN收发的常用功能和一些IO,以及用户交互封装了一下,然后给了一个外壳,就可以完成各种测试任务了,那么软件剩下的部分其实是上千个测试脚本的管理,这个不复杂嘛,实在不行我们可以直接用Win的文件系统嘛!

测试用例的不确定性导致了我下定决心使用脚本语言解决这个问题,让测试能足够的灵活,配置文件可管理,以后也能向后兼容。

设计

我初步设计,Javascript需要以下基础功能:

1、程序的输出显示

提供了log,print,alert等函数,看名字也知道是干嘛的了

2、程序的输入:

由于C#没有输入框,我单独写了一个InputBox,主要就靠这个输入。其次还提供了confirm函数来输入布尔值。

3、程序的文件和网络IO

使用get函数来获取URL中的数据,同时提供文件的读写和追加写入功能

4、CAN的收发功能

这里需要提供CAN信号的管理,CAN信号的发送和等待收取,以及CAN信号的周期后台发送、停止发送功能。这一部分才是核心。

技术选型采用了C#,.NET 4。

Javascript的引擎是Noesis.javascript,由于不需要太美观,所以使用Winform更加方便一点,再使用ElementHost融合一些WPF的控件,做到要灵活的地方能灵活,定死的地方开发快速。

我对自己的技术选型还是很自信的,总而言之,我认为是做到了严肃活泼的地步。

(但是对自己的界面美观程度很不自信……)

最后IDE大概是这个样子的:



IDE只是其中一个模块,但是是其中最强大功能模块了。

JavaScript和C#的融合

其实我当初想用Python作为融合的脚本语言的,但是考虑到JS引擎小巧,可以带在DLL里跑,最后还是选型了JS。

JS的缺点非常明显,尤其是类型很弱这样的问题,使得开发API的时候一定要吃透JS和C#调用的规律。而且说来惭愧,因为这是测试任务,JS异步的特性在这里没有一点发挥(又跑题了)

我在工程里新建了一个JavascriptEngine类,用来包装一个JS引擎,我这个程序所有的测试用例都只在一个容器中运行,减少开销。

首先Import动态链接库

using Noesis.Javascript;

随后在类里新建一个静态的上下文(Context我也不知道怎么翻译比较好)

static JavascriptContext ctx;

随后在初始化代码中初始化:

static JavaScriptEngine() {
try {
ctx = new JavascriptContext();
//导入函数的js文件
ctx.SetParameter("$", new JavaScriptUtility());
runFile("UserLib.js");
} catch (Exception e) {
Logger.logError(e);
}
}

这个时候可以加在一些你自己写的库函数和类,JavaScriptUtility是我写的一个用来承载常用函数的类,因为之前写jquery比较多,比较熟悉$符号,所以沿用了jquery的符号。

这个时候我如果在JavaScriptUtility里新增一个函数:

public class JavaScriptUtility {
public static void alert(string queryInfo, string title) {
MessageBox.Show(queryInfo, title, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}

这个时候你就可以在引擎中调用这个函数:

ctx.Run("$.alert('Hello noesis.javascript','alert')");

这个时候就可以看到你执行的代码。

如果你想兼容风格,方便移植一些浏览器上写的代码可以这样:

var alert = function(text,title){
$.alert(text,title);
};

像这样封装一下就好,需要注意的是该引擎不支持胖括号的写法,你可以这么写:

function alert(text,title){
$.alert(text,title);
};

但是不能这么写:

var alert = (text,title)=>{
$.alert(text,title);
};

我已经踩过坑了,浏览器上好好的代码,上了Noesis就挂逼了,谁也不知道怎么回事。

顺便说一下类型问题,类型系统还是比较智能的,比如你写了两个函数,第一个是

void fun(object u);

你又重载了一次:

void fun(int u);

这个时候如果你输入数字去调用,会调用第二个,输入字符串就会调用第一个。

总结

对于能固定下来的任务,不要想着使用脚本,使用脚本会增大使用人员的门槛,咱这里已经不讨论效率问题了,效率差100倍我也不惊讶。

需要使用脚本引擎的是,变化大,而且往往以后也不能确定怎么改,而且可能随时要改的任务。

脚本的通用性比较好,但是大多数从事汽车行业的人就算会写CAPL也不一定会JS。

软件的编写,除了考虑个人的奋斗,也要考虑历史的进程啊!

浅论Javascript在汽车信号测试中的应用的更多相关文章

  1. 【总结】浅谈JavaScript中的接口

    一.什么是接口 接口是面向对象JavaScript程序员的工具箱中最有用的工具之一.在设计模式中提出的可重用的面向对象设计的原则之一就是“针对接口编程而不是实现编程”,即我们所说的面向接口编程,这个概 ...

  2. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  3. 浅谈JavaScript中的null和undefined

    浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...

  4. 浅谈JavaScript中的正则表达式(适用初学者观看)

    浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...

  5. 浅谈JavaScript中的Function引用类型

    引言 在JavaScript中最有意思的就是函数了,这一切的根源在于函数实际上是一个对象.每一个函数都是Function类型的实例,而且都和其他引用类型的实例一样具有属性和方法.函数作为一个对象,因此 ...

  6. 【ASP.NET MVC系列】浅谈jqGrid 在ASP.NET MVC中增删改查

    ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...

  7. 浅谈javascript函数节流

    浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...

  8. 浅谈JavaScript浮点数及其运算

    原文:浅谈JavaScript浮点数及其运算     JavaScript 只有一种数字类型 Number,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的.浮点数的精度问题 ...

  9. JavaScript 最终将在编程语言中占统治地位?

    JavaScript 最终将在编程语言中占统治地位? JavaScript 现在是大多数开发者都会使用的编程语言.网络效应会推动它成为有史以来第一个真正占统治地位的编程语言吗? 大约十年前,编程的方式 ...

随机推荐

  1. iphone与安卓的兼容性问题汇总

    1.日期问题 当使用yyyy-mm-dd格式时,iphone不认,安卓没问题 解决办法:new Date(res.data[i].inventoryDate.replace(/-/g, "/ ...

  2. java中的基本jdbc中mvc基本示例

    数据库: 包文件: Student.java 1 package com.model; 2 3 public class Student { 4 private int id; 5 private S ...

  3. 在 WPF 中使用 Path 路径

    在 WPF 中总会修改 Button 的 Style,比如一个自定义的 Close 按钮.刚入门的可能会用一张 PNG 格式的图片来做这个按钮的 Icon,但这个是不优雅的.而且你要改的时候还得去操作 ...

  4. 浅谈HTTP中Get与Post的区别[转载]

    Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP ...

  5. XJOI练习2神奇的供水系统

    神奇的供水系统 在游遍神秘岛过程中,Z4发现每一个小岛上都有若干个奇怪的类似小水缸似的立方体,这另到Z4相当迷惑不解!这天晚上,忽然下起了一场大雨,在中心岛小树屋上类似那个圆形石槽中间的小孔中涌出了一 ...

  6. laravel Scout包在elasticsearch中的应用

    laravel Scout包在elasticsearch中的应用 laravel的Scout包是针对自身的Eloquent模型开发的基于驱动的全文检索引擎.意思就是我们可以像使用ORM一样使用检索功能 ...

  7. CF #401 (Div. 2) C.Alyona and Spreadsheet (思维)

    题意:给你n行m列的数组,和k次的询问,问从l行到r行是否存在一个非递增的列 思路:看到这道题的数据量我们就知道直接暴力不可取,所以我们采用了预处理的方法,我们记录下来每一行的最长的非递减的列的开头的 ...

  8. 构造器和多态(Chapter8.3)

    构造器不具有多态性(它们是static方法,只不过该static声明是隐式的),但还是非常有必要理解构造器怎样通过多态在复杂的层次结构中运作,这一理解将有助于大家避免一些令人不快的困扰. 在main中 ...

  9. JS弹出框

    一.JS三种最常见的对话框 1.alert()警告框      alert是警告框,只有一个按钮"确定"无返回值,警告框经常用于确保用户可以得到某些信息.当警告框出现后,用户需要点 ...

  10. Oracle的基本学习(二)—基本查询

    一.基本查询语句 (1)查看当前用户 show user;   (2)查看当前用户下的表 select * from tab;   (3)查看员工表的结构 desc emp;   (4)选择全部列 S ...