作者: 陈辉平

前言

鸿蒙设备系统协议众多,每次设备发货我们都要测试验证协议是否通过,我们开发了协议模拟器,采用自动测试,能快速回归验证鸿蒙系统的稳定性和质量

模拟器

1、wifi协议测试模拟器

@Component
export struct WifiComponent{

@ObjectLink wifiBean: TestBean

aboutToAppear(){
//this.listenWifi()
}
scanAvailableWifi(){
WifiViewModel.canScanAvailableWifi(value => {
if(value){
this.wifiBean.isPass = true
}else{
this.wifiBean.isPass = false
}
})
}

listenWifi(){
WifiViewModel.listenWifiState(wifiState => {
if(1=== wifiState){
this.scanAvailableWifi()
}
})
}
build(){
Column() {
Row() {
Button('wifi', {type: ButtonType.Normal})
.buttonExtendStyle()
.onClick(() => {
this.wifiBean.isPass = undefined
WifiViewModel.checkWifi(isActive => {
if(isActive){
this.scanAvailableWifi()
}else{
promptAction.showToast({message: 'wifi未开启'})
this.wifiBean.isPass = false

          }
        })

      })
    Text(this.wifiBean.isPass == true ? Constants.PASS : (this.wifiBean.isPass == false ? Constants.UN_PASS : ''))
      .fontSize(20)
      .fontWeight(500)
      .margin({ left: 10, right: 10 })
  }
}.width('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Start)

}
}

@Extend(Button) function buttonExtendStyle(){
.fontSize(15)
.fontWeight(500)
.width('60%')
.height(50)
.borderRadius(10)

2、RS232协议模拟器

@Component
export struct RS232Component {
@ObjectLink RS232Bean1: TestBean
@ObjectLink RS232Bean2: TestBean
@ObjectLink RS232Bean3: TestBean
@ObjectLink RS232Bean4: TestBean
@Prop @Watch('autoTestRS232Update') isAutoTest: boolean
timer: number = -1
index: number = 0
@State innerAutoTest: boolean = false
timer2: number = -1

aboutToAppear() {
SERIALS_PORT.forEach((port, index) =>{
RS232ViewModel.setSerial(port)
RS232ViewModel.openSerial(port)
}, index => index)
// setTimeout(()=>{
// listenAll([this.RS232Bean1, this.RS232Bean2, this.RS232Bean3, this.RS232Bean4])
// },1000)

}

// onPageShow(){
// listenAll([this.RS232Bean1, this.RS232Bean2, this.RS232Bean3, this.RS232Bean4])
// }

autoTestRS232Update(propName: string) {
if (this.isAutoTest) {
this.autoTest()
} else {
clearInterval(this.timer)
this.index = 0
}
}

autoTest() {
clearInterval(this.timer)
this.timer = setInterval(items => {
let len = items.length
if (this.index < len) {
testEach(ITEMS[this.index], [this.RS232Bean1, this.RS232Bean2, this.RS232Bean3, this.RS232Bean4], SERIALS_232_NAME)
this.index++
}
}, 1000, ITEMS)
}

showResult(index: number): string {
switch (index) {
case 0:
return this.RS232Bean1.description
case 1:
return this.RS232Bean2.description
case 2:
return this.RS232Bean3.description
case 3:
return this.RS232Bean4.description
}
}

@Builder builderItem(index: number) {
Row() {
Button(SERIALS_232_NAME[index], { type: ButtonType.Normal })
.buttonExtendStyle()
.enabled(this.innerAutoTest ? false : true)
.onClick(() => {
testEach(index, [this.RS232Bean1, this.RS232Bean2, this.RS232Bean3, this.RS232Bean4], SERIALS_232_NAME)
})

  Text(this.showText(index))
    .fontSize(20)
    .fontWeight(500)
    .margin({ left: 10, right: 10 })
}.margin({ bottom: index === 3 ? 0 : 20 })

}

showText(index: number): string {
// if (isTestVersion) {
// return this.passResult(index)
// } else {
// return this.showResult(index) ? this.showResult(index) : ''
// }
return this.showResult(index) ? this.showResult(index) : ''
}

passResult(index: number): string {
switch (index) {
case 0:
return this.RS232Bean1.isPass == undefined ? '' : (this.RS232Bean1.isPass ? Constants.PASS : Constants.UN_PASS)
case 1:
return this.RS232Bean2.isPass == undefined ? '' : (this.RS232Bean2.isPass ? Constants.PASS : Constants.UN_PASS)
case 2:
return this.RS232Bean3.isPass == undefined ? '' : (this.RS232Bean3.isPass ? Constants.PASS : Constants.UN_PASS)
case 3:
return this.RS232Bean4.isPass == undefined ? '' : (this.RS232Bean4.isPass ? Constants.PASS : Constants.UN_PASS)
}
}

build() {
Column() {

  ForEach(ITEMS, ele => {
    this.builderItem(ele)
  }, ele => ele)
}.width('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Start)

}
}

@Extend(Button) function buttonExtendStyle() {
.fontSize(15)
.fontWeight(500)
.width('50%')
.height(50)
.borderRadius(10)

3、RS485协议模拟器

//4个RS485串口

const ITEMS = [0, 1, 2, 3]

@Component
export struct RS485Component {
@ObjectLink RS485Bean1: TestBean
@ObjectLink RS485Bean2: TestBean
@ObjectLink RS485Bean3: TestBean
@ObjectLink RS485Bean4: TestBean

@Prop @Watch('autoTestRS485Update')isAutoTest : boolean

timer : number = -1

timer1: number = -1
index: number = 0

aboutToAppear() {
SERIALS_PORT.forEach((port, index) =>{
RS485ViewModel.setSerial(port)
RS485ViewModel.openSerial(port)
}, index => index)
// setTimeout(() => {
// listenAll([this.RS485Bean1, this.RS485Bean2, this.RS485Bean3, this.RS485Bean4])
// }, 1000)
}

autoTestRS485Update(propName: string){
clearTimeout(this.timer1)
this.timer1 = setTimeout(() => {
if(this.isAutoTest){
this.autoTest()
}else{
clearInterval(this.timer)
this.index = 0
}
}, 8000) // 自动测试 RS232和RS485串口不能同时收到数据
}

autoTest(){
clearInterval(this.timer)
this.timer = setInterval(items => {
let len = items.length
if(this.index < len){
testEach(ITEMS[this.index], [this.RS485Bean1, this.RS485Bean2, this.RS485Bean3, this.RS485Bean4], SERIALS_485_NAME)
this.index++
}
}, 1000,ITEMS)
}

@Builder builderItem(index: number) {
Row() {
Button(SERIALS_485_NAME[index], {type: ButtonType.Normal})
.buttonExtendStyle()
.onClick(() => {
testEach(index, [this.RS485Bean1, this.RS485Bean2, this.RS485Bean3, this.RS485Bean4], SERIALS_485_NAME)
})

  Text(this.showText(index))
    .fontSize(20)
    .fontWeight(500)
    .margin({ left: 10, right: 10 })

}.margin({bottom: 20})

}

build() {
Column() {
ForEach(ITEMS, ele => {
this.builderItem(ele)
}, ele => ele)
}.width('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Start)
}

showText(index: number) : string {
// if (isTestVersion) {
// return this.passResult(index)
// } else {
// return this.showResult(index) ? this.showResult(index) : ''
// }
return this.showResult(index) ? this.showResult(index) : ''
}

passResult(index: number): string {
switch (index) {
case 0:
return this.RS485Bean1.isPass == undefined ? '' : (this.RS485Bean1.isPass ? Constants.PASS: Constants.UN_PASS )
case 1:
return this.RS485Bean2.isPass == undefined ? '' : (this.RS485Bean2.isPass ? Constants.PASS: Constants.UN_PASS )
case 2:
return this.RS485Bean3.isPass == undefined ? '' : (this.RS485Bean3.isPass ? Constants.PASS: Constants.UN_PASS )
case 3:
return this.RS485Bean4.isPass == undefined ? '' : (this.RS485Bean4.isPass ? Constants.PASS: Constants.UN_PASS )
}
}
showResult(index: number): string{
switch (index){
case 0:
return this.RS485Bean1.description
case 1:
return this.RS485Bean2.description
case 2:
return this.RS485Bean3.description
case 3:
return this.RS485Bean4.description
}
}

}

@Extend(Button) function buttonExtendStyle(){
.fontSize(15)
.fontWeight(500)
.width('50%')
.height(50)
.borderRadius(10)
}

4、Gps协议模拟器

@Component
export struct GpsComponent {
@ObjectLink gpsBean: TestBean

controlLight(isOpen: boolean, location?: geolocation.Location ){
promptAction.showToast({message: 'XXX打开A1:'+isOpen})

if(isOpen ){
  if(location.latitude != 0 && location.longitude != 0){
    ledApi.setled(LedSwitch.LED_GPS_ON)
  }
}else{
  ledApi.setled(LedSwitch.LED_GPS_OFF)
}

}

build() {
Column() {
Row() {
Button(this.gpsBean.name, {type: ButtonType.Normal})
.buttonExtendStyle()
.onClick(() => {
this.gpsBean.isPass = false

        geolocation.requestEnableLocation((err, isOpen) => {
          if(isOpen){
            geoLocationManager.getCurrentLocation()
              .then(location => {
                this.gpsBean.isPass = true
                this.gpsBean.extraInfo.latitude = location.latitude.toFixed(2).toString()
                this.gpsBean.extraInfo.longitude = location.longitude.toFixed(2).toString()
                this.controlLight(true, location)

              }).catch(err => {
              this.gpsBean.isPass = false
              promptAction.showToast({message: '获取位置失败'})
            })
          }else{
              promptAction.showToast({message: '位置服务未开启'})
              return
          }
        })

      })
    Text(this.gpsBean.isPass == true ? `(${this.gpsBean.extraInfo.latitude}, ${this.gpsBean.extraInfo.longitude} )` : '')
      .fontSize(20)
      .fontWeight(500)
      .margin({ left: 10, right: 10 })
  }

}.width('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Start)

}
}
@Extend(Button) function buttonExtendStyle(){
.fontSize(15)
.fontWeight(500)
.width('60%')
.height(50)
.borderRadius(10)
}

总结

采用自动化测试,可以提升鸿蒙系统的质量和效率,后面批量发货,批量生产提供了快速回归验证的能力。

更多原创内容请关注:中软国际OpenHarmony技术团队

入门到精通、技巧到案例,系统化分享OpenHarmony开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐