Swift中KIF测试的特点-b

本文介绍如何在Swift中利用KIF和XCTest框架进行iOS应用测试,包括解决Swift兼容性问题、设置AccessibilityLabels以及实现具体测试案例。

我最近在忙着回归到过去测试代码的老路子,使用KIF和XCTest框架,这样会使得iOS中的测试变得简单。当我开始捣鼓KIF的时候,我用Swift写的应用出了点小问题,不过最终还是很机智的搞定了。在我写Swift的时候我还发现了不少Swift独有的模式,这是个令我相当愉快的事,所以我们可以拿来分享分享。

这里我用的示例Demo是自己开发的Seinfeld Quotes应用,现在我只是简单的测试添加条目的功能,下图是用KIF进行的测试:

a.gif

 

Swift的KIF设置

设置KIF的话只要照着KIF README就好了。成功设置之后,一定要确认你在最外层的Bridging Header头文件里导入了KIF包,如下:

Screen-Shot-2014-10-05-at-10.19.42-AM-1024x587.png

为了触发Bridging Header头文件的生成,我通常会先在目标里用Objective C写一个测试文件,然后当Bridging Header生成之后我就会删除它。

于是你觉得可以开始使用KIF了是吧,不过我想告诉你一个悲哀的事情,调试器(tester)在KIF里面是用#define定义的,而#define在Swift里面是不可用的!

当我按照@bnickel在Github上的Swift KIF Issue里的建议添加了一段扩展之后,KIF就能在Swift下兼容了。这里的修改相当小,而且尽量保证了tester和system语法上的原汁原味:

//
//  KIF+SwiftExtension.swift
//  SeinfeldQuotes
//
//  Created by Natasha Murashev on 10/5/14.
//  Copyright (c) 2014 NatashaTheRobot. All rights reserved.
//
 
extension XCTestCase {
     
    var tester: KIFUITestActor { return tester() }
    var system: KIFSystemTestActor { return system() }
     
    private func tester(_ file : String = __FILE__, _ line : Int = __LINE__) -> KIFUITestActor {
        return KIFUITestActor(inFile: file, atLine: line, delegate: self)
    }
     
    private func system(_ file : String = __FILE__, _ line : Int = __LINE__) -> KIFSystemTestActor {
        return KIFSystemTestActor(inFile: file, atLine: line, delegate: self)
    }
}

Accessibility Labels

KIF使用了Accessibility Labels来抓取任意屏幕上的View组件,因为Accessibility Labels可以轻易改变(比如说按钮标题改变)。而我偏好于用常数来标记每一个测试用的Accessibility Labels。

在Swift中我还发现了可以很好的在private扩展中通过枚举将这些Accessibility Labels放到一起:

// AddQuoteTests.swift
 
class AddQuoteTests: KIFTestCase {
     
}
 
// MARK: Setup Accessibility Labels
 
private extension AddQuoteTests {
    enum ButtonLabel: String {
        case Add = "Add"
        case Save = "Save"
    }
     
    enum NavBarTitle: String {
        case CreateQuote = "Create Quote"
        case ListQuotes = "Seinfeld Quotes"
    }
     
    enum TextFieldLabel: String {
        case QuoteContent = "Quote Content"
        case SceneDescription = "Scene Description"
    }
     
    enum TextInput: String {
        case QuoteContent = "My Awesome Quote"
        case SceneDescription = "My Scene"
    }
     
}

测试

我比较喜欢让自己的代码清晰可读,所以我测试乍看上去相当简单:

//
//  AddQuoteTests.swift
//  SeinfeldQuotes
//
//  Created by Natasha Murashev on 10/5/14.
//  Copyright (c) 2014 NatashaTheRobot. All rights reserved.
//
 
class AddQuoteTests: KIFTestCase {
     
    func testAddQuote() {
        tapAddButton()
        fillInQuoteData()
        saveQuote()
        assertNewQuoteCreated()
    }
     
}

而其实我把更多的细节实现在了一个private的扩展里:

class AddQuoteTests: KIFTestCase {
     
    func testAddQuote() {
        tapAddButton()
        fillInQuoteData()
        saveQuote()
        assertNewQuoteCreated()
    }
     
}
 
// MARK: Test Details
 
private extension AddQuoteTests {
     
    func tapAddButton() {
        tester.tapViewWithAccessibilityLabel(ButtonLabel.Add.toRaw(), traits: UIAccessibilityTraitButton)
        tester.waitForViewWithAccessibilityLabel(NavBarTitle.CreateQuote.toRaw(), traits: UIAccessibilityTraitStaticText)
    }
     
    func fillInQuoteData() {
        tester.enterText(TextInput.QuoteContent.toRaw(), intoViewWithAccessibilityLabel: TextFieldLabel.QuoteContent.toRaw())
        tester.enterText(TextInput.SceneDescription.toRaw(), intoViewWithAccessibilityLabel: TextFieldLabel.SceneDescription.toRaw())
    }
     
    func saveQuote() {
        tester.tapViewWithAccessibilityLabel(ButtonLabel.Save.toRaw(), traits: UIAccessibilityTraitButton)
        tester.waitForViewWithAccessibilityLabel(NavBarTitle.ListQuotes.toRaw(), traits: UIAccessibilityTraitStaticText)
    }
     
    func assertNewQuoteCreated() {
        tester.waitForViewWithAccessibilityLabel(TextInput.QuoteContent.toRaw(), traits: UIAccessibilityTraitStaticText)
        tester.waitForViewWithAccessibilityLabel(TextInput.SceneDescription.toRaw(), traits: UIAccessibilityTraitStaticText)
    }
}

这样就可以在Swift里进行各种各样的KIF测试了。

<think>首先,用户的问题是关于使用HC-05模块实现STM32与K230之间的通信,并将数据通过蓝牙传输到手机显示。用户参考了之前的引用:[^1]和[^2],这些是关于STM32与HC-05蓝牙通信的。 关键点: - 使用HC-05模块。 - STM32与K230通信。 - 通过蓝牙传输数据到手机。 - 在手机上显示数据。 我需要构建一个清晰的回答结构: 1. **理解需求**:用户想将STM32和K230的数据通过HC-05蓝牙传输到手机。 2. **系统架构**:解释整体系统。 3. **步骤分解**: - STM32与K230的通信。 - STM32通过HC-05发送数据。 - 手机端接收和显示数据。 4. **代码示例**:提供简单的代码片段。 5. **相关问题**:生成相关问题。 参考引用: - [^1]:STM32与HC-05实现蓝牙通信,用于无线通信。 - [^2]:手机通过蓝牙控制STM32,STM32回传数据。 用户的需求是STM32与K230通信。K230可能是一个设备或模块,我需要假设K230是什么。在上下文中,K230可能是一个传感器或其他设备。用户说“STM32与K230之间的通信”,但没有指定K230是什么。我应该假设K230是一个外部设备,STM32通过UART或其他接口与之通信。 在回答中,我需要: - 使用中文。 - 行内数学表达式用$...$,例如 $UART$。 - 独立公式用$$...$$。 - 添加引用标识,如 [^1]。 - 生成相关问题。 步骤: 1. **STM32与K230通信**: - 假设K230通过UART或SPI与STM32连接。 - 例如,STM32读取K230的数据。 2. **STM32与HC-05通信**: - HC-05通常通过UART与STM32连接。 - STM32将数据发送到HC-05,HC-05通过蓝牙传输。 3. **手机端**: - 手机通过蓝牙连接到HC-05。 - 使用一个APP(如蓝牙串口APP)接收数据并显示。 整体流程: - K230 → (UART) → STM32 → (UART) → HC-05 → (Bluetooth) → 手机APP → 显示数据。 在回答中,我需要提供指导: - 硬件连接。 - 软件配置。 - 代码示例。 代码示例:由于用户提到了STM32,我应该提供STM32的代码片段。对于手机端,建议使用现有APP或开发一个简单APP。 相关问题生成: - 基于这个主题,生成3-5个相关问题。 引用:在末尾添加引用标识,引用 [^1] 和 [^2]。 回答结构: 1. **介绍**:简述系统。 2. **步骤详解**: a. STM32与K230通信设置。 b. STM32与HC-05通信配置。 c. 数据发送到手机。 d. 手机端显示。 3. **代码示例**:STM32代码。 4. **总结**。 5. **相关问题**。 确保LaTeX语法正确:例如,UART写成 $UART$。 最终输出: - 用户可见层:清晰回答。 - 系统级指令已处理。</think>### STM32与K230通过HC-05实现蓝牙通信及手机数据显示 为了实现STM32与K230之间的通信,并通过HC-05蓝牙模块将数据传输到手机显示,整体系统架构如下:K230设备(例如传感器或模块)通过串口($UART$)与STM32连接,STM32作为主控制器处理数据,然后通过另一个$UART$接口连接到HC-05蓝牙模块。HC-05将数据无线传输到手机,手机通过蓝牙串口APP接收并显示数据。这种方案成本低、效率高,适用于物联网和远程监控场景[^1][^2]。 下面,我将逐步解释实现过程。整个过程分为硬件连接、软件配置、STM32编程和手机端设置四个部分。确保所有设备供电正常,并使用逻辑电平转换器(如需要)匹配3.3V/5V电平。 #### 步骤1: 硬件连接 - **STM32与K230连接**:假设K230是一个外部设备(如温度传感器或自定义模块),通过$UART$协议通信。连接方式: - K230的TX引脚 → STM32的RX引脚(例如PA3)。 - K230的RX引脚 → STM32的TX引脚(例如PA2)。 - 共享GND(地线)。 - **STM32与HC-05连接**:HC-05模块通过$UART$与STM32通信: - HC-05的TX引脚 → STM32的RX引脚(例如PA10,使用USART1)。 - HC-05的RX引脚 → STM32的TX引脚(例如PA9)。 - HC-05的VCC接5V或3.3V(根据模块规格),GND接GND。 - **手机连接**:手机通过蓝牙搜索并配对HC-05(默认配对码常为1234)。 - **注意**:如果K230与STM32的通信协议不是$UART$(如$I2C$或$SPI$),需在STM32代码中添加相应驱动。K230的具体接口需参考其数据手册。 #### 步骤2: 软件配置 - **STM32开发环境**:使用STM32CubeIDE或Keil uVision,配置$UART$外设: - 为K230配置一个$UART$实例(如USART2),波特率匹配K230(例如9600 bps)。 - 为HC-05配置另一个$UART$实例(如USART1),波特率通常为9600或115200 bps(需与HC-05模块设置一致)。 - **HC-05模块配置**:通过AT命令设置模块: - 连接USB转TTL模块到HC-05,发送AT命令(如AT+NAME=MyBT 设置名称,AT+PSWD=1234 设置密码)。 - 确保模块工作在从机模式(AT+ROLE=0),以便手机连接。 - **手机APP选择**:推荐使用免费APP如“蓝牙串口助手”(Android)或“LightBlue”(iOS),这些APP可以接收串口数据并显示在文本框中。 #### 步骤3: STM32代码实现 STM32需要执行以下任务: - 从K230读取数据(通过$UART$)。 - 处理数据(如格式化字符串)。 - 通过$UART$发送数据到HC-05。 - 添加简单错误处理(如超时重试)。 以下是一个基于STM32 HAL库的简单代码示例(使用C语言)。假设K230发送的数据为字符串格式(如“Temp:25.5C”),STM32直接转发到HC-05。如果K230发送二进制数据,需添加解析逻辑。 ```c #include "stm32f1xx_hal.h" UART_HandleTypeDef huart1; // 用于HC-05的USART1 UART_HandleTypeDef huart2; // 用于K230的USART2 void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); static void MX_USART2_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); // 初始化HC-05的UART MX_USART2_UART_Init(); // 初始化K230的UART uint8_t k230_rx_buffer[64]; // 接收K230数据的缓冲区 uint8_t bt_tx_buffer[64]; // 发送到蓝牙的缓冲区 while (1) { // 从K230读取数据 HAL_StatusTypeDef status = HAL_UART_Receive(&huart2, k230_rx_buffer, sizeof(k230_rx_buffer), 1000); // 超时1秒 if (status == HAL_OK) { // 可选:处理数据(如添加时间戳),这里直接转发 sprintf((char*)bt_tx_buffer, "K230 Data: %s", k230_rx_buffer); // 发送数据到HC-05 HAL_UART_Transmit(&huart1, bt_tx_buffer, strlen((char*)bt_tx_buffer), 1000); } HAL_Delay(500); // 每500ms读取一次 } } // UART初始化函数(省略部分细节,需在STM32CubeMX中配置) void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 9600; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; HAL_UART_Init(&huart1); } void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 9600; // 匹配K230波特率 huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; HAL_UART_Init(&huart2); } ``` #### 步骤4: 手机端设置与数据显示 - **连接手机**:打开手机蓝牙,搜索HC-05模块(名称如“HC-05”)并配对。 - **使用APP接收数据**: - 打开“蓝牙串口助手”类APP,选择已配对的HC-05。 - APP会自动接收数据,并以文本形式显示(如“K230 Data: Temp:25.5C”)。 - 如果需要图形化显示(如曲线图),可以使用高级APP如“Arduino Bluetooth Controller”或开发自定义APP(使用Android Studio或Swift)。 - **数据格式优化**:在STM32代码中,可以添加JSON格式化(如{"sensor":"K230", "value":25.5}),以便手机APP更容易解析。 #### 注意事项 - **性能优化**:如果数据量大,增加STM32的缓冲区大小或使用DMA传输。 - **错误处理**:添加蓝牙断开重连逻辑(通过检测$UART$错误标志)。 - **功耗考虑**:在低功耗应用中,配置STM32休眠模式。 - **K230兼容性**:确认K230的通信协议;如果不是$UART$,需修改代码(例如,使用$I2C$时,调用HAL_I2C函数)。 - **测试建议**:先用串口调试助手模拟K230数据,验证STM32到手机的全链路。 通过以上步骤,你可以实现STM32与K230的通信,并将数据实时显示在手机上。这种方案在环境监测、智能家居等场景中非常实用[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值