golang在浏览器中运行Go WASM测试插件库wasmbrowsertest的使用

Golang在浏览器中运行Go WASM测试插件库wasmbrowsertest的使用

wasmbrowsertest是一个简化在浏览器中运行Go WASM测试的工具。

快速开始

  1. 安装工具:
go install github.com/agnivade/wasmbrowsertest@latest
  1. 将二进制文件重命名为go_js_wasm_exec
mv $GOPATH/bin/wasmbrowsertest $GOPATH/bin/go_js_wasm_exec
  1. 确保$GOBIN在$PATH中

  2. 运行测试:

GOOS=js GOARCH=wasm go test

工作原理

go test允许调用不同的二进制文件来运行测试。有两种方法:

  1. 在$PATH中有一个名为go_js_wasm_exec的二进制文件
  2. 或者在测试中设置-exec标志

示例代码

下面是一个完整的示例展示如何使用wasmbrowsertest:

// main_test.go
package main

import "testing"

func TestAdd(t *testing.T) {
    result := add(2, 3)
    if result != 5 {
        t.Errorf("Expected 5, got %d", result)
    }
}

func add(a, b int) int {
    return a + b
}

运行测试:

GOOS=js GOARCH=wasm go test

CPU性能分析

可以在测试时进行CPU性能分析:

GOOS=js GOARCH=wasm go test -cpuprofile cpu.prof

运行非测试程序

也可以运行非测试程序:

GOOS=js GOARCH=wasm go run main.go

如果想在浏览器中查看应用程序运行情况:

WASM_HEADLESS=off GOOS=js GOARCH=wasm go run main.go

在CI中使用

Travis CI配置

addons:
  chrome: stable

install:
- go install github.com/agnivade/wasmbrowsertest@latest
- mv $GOPATH/bin/wasmbrowsertest $GOPATH/bin/go_js_wasm_exec
- export PATH=$GOPATH/bin:$PATH

GitHub Actions配置

on: [push, pull_request]
name: Unit Test
jobs:
  test:
    strategy:
      matrix:
        go-version: [1.xx.x]
        os: [ubuntu-latest]
    runs-on: ${{ matrix.os }}
    steps:
    - name: Install Go
      uses: actions/setup-go@v2
      with:
        go-version: ${{ matrix.go-version }}
    - name: Install chrome
      uses: browser-actions/setup-chrome@latest
    - name: Install dep
      run: go install github.com/agnivade/wasmbrowsertest@latest
    - name: Setup wasmexec
      run: mv $(go env GOPATH)/bin/wasmbrowsertest $(go env GOPATH)/bin/go_js_wasm_exec
    - name: Checkout code
      uses: actions/checkout@v2

常见问题解决

命令行和环境变量总长度超过限制

如果出现total length of command line and environment variables exceeds limit错误,可以使用cleanenv工具:

go install github.com/agnivade/wasmbrowsertest/cmd/cleanenv@latest

export GOOS=js GOARCH=wasm
cleanenv -remove-prefix GITHUB_ -- go test -cover ./...

覆盖数据提示(Go 1.20+)

对于Go 1.20及以上版本,建议使用:

go test -test.gocoverdir=/path/to/coverage

然后处理覆盖数据:

go tool covdata -i /path/to/coverage -o coverage.out

这个工具大大简化了在浏览器中测试Go WASM代码的过程,使得开发体验更加流畅。


更多关于golang在浏览器中运行Go WASM测试插件库wasmbrowsertest的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang在浏览器中运行Go WASM测试插件库wasmbrowsertest的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用wasmbrowsertest在浏览器中测试Go WASM代码

wasmbrowsertest是一个用于在浏览器环境中测试Go WebAssembly(WASM)代码的插件库。它允许你在真实的浏览器环境中运行测试,而不仅仅是Node.js环境。

安装wasmbrowsertest

首先安装wasmbrowsertest:

go get github.com/agnivade/wasmbrowsertest

基本使用

假设我们有一个简单的WASM模块需要测试:

// main.go
package main

import "syscall/js"

func add(a, b int) int {
    return a + b
}

func main() {
    js.Global().Set("goAdd", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        return add(args[0].Int(), args[1].Int())
    }))
    
    select {} // 保持程序运行
}

创建对应的测试文件:

// main_test.go
package main

import (
    "testing"
)

func TestAdd(t *testing.T) {
    got := add(2, 3)
    if got != 5 {
        t.Errorf("add(2, 3) = %d; want 5", got)
    }
}

运行测试

使用wasmbrowsertest运行测试:

GOOS=js GOARCH=wasm go test -exec=$GOPATH/bin/wasmbrowsertest

更复杂的示例

测试与浏览器API交互的代码:

// dom.go
package main

import "syscall/js"

func registerCallbacks() {
    js.Global().Set("updateDOM", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        document := js.Global().Get("document")
        element := document.Call("getElementById", "myDiv")
        element.Set("innerHTML", "Hello from WASM!")
        return nil
    }))
}

对应的测试文件:

// dom_test.go
package main

import (
    "testing"
    
    "github.com/agnivade/wasmbrowsertest"
)

func TestDOMUpdate(t *testing.T) {
    // 创建一个虚拟DOM环境
    page := wasmbrowsertest.NewPage(t)
    defer page.Close()
    
    // 设置测试HTML
    html := `
    <html>
        <body>
            <div id="myDiv"></div>
        </body>
    </html>
    `
    page.SetContent(html)
    
    // 注册并调用我们的WASM函数
    registerCallbacks()
    page.Call("updateDOM")
    
    // 验证结果
    result := page.Eval("document.getElementById('myDiv').innerHTML")
    if result != "Hello from WASM!" {
        t.Errorf("Expected 'Hello from WASM!', got '%s'", result)
    }
}

高级特性

模拟浏览器API

func TestLocalStorage(t *testing.T) {
    page := wasmbrowsertest.NewPage(t)
    defer page.Close()
    
    // 模拟localStorage
    page.Eval(`window.localStorage = {
        store: {},
        getItem: function(key) { return this.store[key] || null; },
        setItem: function(key, value) { this.store[key] = value; }
    }`)
    
    // 测试localStorage交互
    page.Eval("localStorage.setItem('test', 'value')")
    val := page.Eval("localStorage.getItem('test')")
    if val != "value" {
        t.Errorf("Expected 'value', got '%s'", val)
    }
}

处理异步操作

func TestAsync(t *testing.T) {
    page := wasmbrowsertest.NewPage(t)
    defer page.Close()
    
    done := make(chan struct{})
    
    // 设置一个回调函数
    page.Global().Set("goCallback", page.FuncOf(func(this js.Value, args []js.Value) interface{} {
        close(done)
        return nil
    }))
    
    // 触发异步操作
    page.Eval(`
        setTimeout(() => {
            goCallback();
        }, 100);
    `)
    
    // 等待回调完成
    <-done
}

配置选项

wasmbrowsertest提供了一些配置选项:

func TestWithOptions(t *testing.T) {
    page := wasmbrowsertest.NewPage(t,
        wasmbrowsertest.WithLogFunc(t.Logf),  // 自定义日志
        wasmbrowsertest.WithStderr(t.Logf),   // 重定向stderr
        wasmbrowsertest.WithStdout(t.Logf),   // 重定向stdout
    )
    defer page.Close()
    
    // 测试代码...
}

总结

wasmbrowsertest为Go WASM代码提供了完整的浏览器环境测试能力,主要特点包括:

  1. 在真实浏览器环境中执行测试
  2. 支持DOM操作测试
  3. 可以模拟浏览器API
  4. 支持异步操作测试
  5. 提供虚拟页面环境

使用wasmbrowsertest可以大大提高Go WASM代码的测试覆盖率和可靠性,确保代码在真实浏览器环境中的行为符合预期。

对于更复杂的测试场景,建议结合常规的Go测试和wasmbrowsertest,前者用于测试纯Go逻辑,后者用于测试浏览器交互部分。

回到顶部