“如果结果不如你所愿,就在尘埃落定前奋力一搏。”——《夏目友人帐》
“有些事不是看到了希望才去坚持,而是因为坚持才会看到希望。”——《十宗罪》
“维持现状意味着空耗你的努力和生命。”——纪伯伦
第六节 Tauri的调试与测试
一. 概述
在本章节的内容中,我们将探讨如何在Tauri的项目中进行测试与调试。
二. 调试
在项目的开发过程中,我们经常需要在项目中对编写的代码进行调试,那么在Tauri项目中,既包含前端部分又包含后端部分,那如何进行功能流程的调试呢?在开发工具中又是如何配置的?
在Tauri项目中前端项目的调试主要依赖于webview的开发者工具来实现的,如:f12,而后端应用的调试主要借助于当下使用的开发工具。(这里的后端主要说的是rust服务代码)
1. WebView 控制台
tauri的webview控制台在开发或调试模式下是打开的,在生产环境下是关闭的,想开启的可以使用第二种方式,即:Cargo !
-
通过F12的方式打开和关闭控制台;
-
通过编程方式打开 DevTools
您可以使用
WebviewWindow::open_devtools
和WebviewWindow::close_devtools
函数控制检查器窗口的可见性:tauri::Builder::default() .setup(|app| { #[cfg(debug_assertions)] // only include this code on debug builds { let window = app.get_webview_window("main").unwrap(); window.open_devtools(); window.close_devtools(); } Ok(()) });
2. Rust开发调试
-
打印输出信息,在Rust中输出信息到控制台,这里的控制台一般为编译器的控制台
println!("Message from Rust: {}", msg);
-
Rust代码中支持仅运行在开发模式下的代码,方式如下:
fn main() { // Whether the current instance was started with `tauri dev` or not. #[cfg(dev)] { // `tauri dev` only code } if cfg!(dev) { // `tauri dev` only code } else { // `tauri build` only code } let is_dev: bool = tauri::is_dev(); // Whether debug assertions are enabled or not. This is true for `tauri dev` and `tauri build --debug`. #[cfg(debug_assertions)] { // Debug only code } if cfg!(debug_assertions) { // Debug only code } else { // Production only code } }
3. 调试工具
调试工具的使用以及配置大家可以参考下官方文档:
在这里我比较推荐大家使用 CrabNebula DevTools,使用方式可以参考:https://docs.crabnebula.dev/devtools/get-started/
这类我们阐述下在VScode 中如何进行调试。
-
第一步:安装插件
在插件市场中 搜索CodeLLDB,并安装:codelldb-win32-x64.vsix, 需要从GitHUb 下载,比较慢;这里我提前下载好了,并推荐离线安装:
下载地址:https://download.csdn.net/download/sxlesq/90250270?spm=1001.2014.3001.5503
离线安装方式
PS D:\elcker\Software\apps\VSCode\bin> .\code --install-extension ..\codelldb-win32-x64.vsix Installing extensions... Extension 'codelldb-win32-x64.vsix' was successfully installed. PS D:\elcker\Software\apps\VSCode\bin>
-
第二步:插件配置
在项目根目录下创建 .vscode 文件,在文件下创建 launch.json 和 task.json 文件
- launch.json
{ "version": "0.2.0", "configurations": [ { "type": "lldb", "request": "launch", "name": "Tauri Development Debug", "cargo": { "args": [ "build", "--manifest-path=./src-tauri/Cargo.toml", "--no-default-features" ] }, "preLaunchTask": "ui:dev" }, { "type": "lldb", "request": "launch", "name": "Tauri Production Debug", "cargo": { "args": ["build", "--release", "--manifest-path=./src-tauri/Cargo.toml"] }, "preLaunchTask": "ui:build" } ] }
-
task.json
{ "version": "2.0.0", "tasks": [ { "label": "ui:dev", "type": "shell", "isBackground": true, "command": "pnpm", "args": ["dev"] }, { "label": "ui:build", "type": "shell", "command": "pnpm", "args": ["build"] } ] }
-
第三步: 添加断点进行调试,前端页面触发就可以使用
三 . 测试
测试在项目开发过程中也比较普遍,通常我们会进行功能的单元测试和集成测试,在Tauri 中提供了利用WebDriver协议进行端到端的测试。但在macos中暂不支持。
1. Tauri Api的模拟
在前端测试中,我们需要编写一些 模拟数据或者模拟环境来进行测试,在Tauri 中他利用 @tauri-apps/api/mocks
模块提供增强。
但是要注意:次测试运行后清除模拟,以撤消运行之间的模拟状态变化!
1)IPC请求模拟
在IPC模拟中,我们可能会碰到以下2中情况:
- 确保进行正确的后端调用
- 模拟后端函数的不同结果
Tauri 提供了 mockIPC 函数来拦截 IPC 请求,具体 API 的详细信息可以在这里查看。
以下是一个IPC模拟示例:
import { beforeAll, expect, test, vi } from "vitest";
import { randomFillSync } from "crypto";
import { mockIPC } from "@tauri-apps/api/mocks";
import { invoke } from "@tauri-apps/api/core";
// jsdom doesn't come with a WebCrypto implementation
beforeAll(() => {
Object.defineProperty(window, 'crypto', {
value: {
// @ts-ignore
getRandomValues: (buffer) => {
return randomFillSync(buffer);
},
},
});
});
test("invoke", async () => {
mockIPC((cmd, args) => {
// simulated rust command called "add" that just adds two numbers
if(cmd === "add") {
return (args.a as number) + (args.b as number);
}
});
// we can use the spying tools provided by vitest to track the mocked function
const spy = vi.spyOn(window, "__TAURI_INTERNALS__.invoke");
expect(invoke("add", { a: 12, b: 15 })).resolves.toBe(27);
expect(spy).toHaveBeenCalled();
});
2)窗口模拟
可以使用该mockWindows()
方法创建假窗口标签。第一个字符串标识“当前”窗口(即您的 JavaScript 认为的窗口)
mockWindows()
仅伪造窗口的存在,但没有窗口属性。要模拟窗口属性,您需要使用以下方法拦截正确的调用mockIPC()
以下是一个窗口模拟示例:
import { beforeAll, expect, test } from 'vitest';
import { randomFillSync } from 'crypto';
import { mockWindows } from '@tauri-apps/api/mocks';
// jsdom doesn't come with a WebCrypto implementation
beforeAll(() => {
Object.defineProperty(window, 'crypto', {
value: {
// @ts-ignore
getRandomValues: (buffer) => {
return randomFillSync(buffer);
},
},
});
});
test('invoke', async () => {
mockWindows('main', 'second', 'third');
const { getCurrent, getAll } = await import('@tauri-apps/api/webviewWindow');
expect(getCurrent()).toHaveProperty('label', 'main');
expect(getAll().map((w) => w.label)).toEqual(['main', 'second', 'third']);
});
2. WebDriver
WebDriver是一种标准化接口,主要用于与 Web 文档交互,主要用于自动化测试。Tauri通过利用跨平台包装器下的本机平台的WebDriver服务器来支持WebDriver接口。
1. 安装依赖
cargo install tauri-driver --locked
确保获取与应用程序正在构建和测试的 Windows Edge 版本相匹配的Microsoft Edge 驱动程序版本。这几乎总是最新 Windows 安装中的最新稳定版本。如果两个版本不匹配,您可能会在尝试连接时遇到 WebDriver 测试套件挂起的情况。
2. 详细使用方法
-
最好测试demo获取:https://github.com/chippers/hello_tauri。
-
使用流程:WebDriver示例
它不是我们学习的重点,这里了解下。官方使用的是; https://www.selenium.dev/
有时间,我们会单独探讨下:Selenium(WEB自动化工具)*