设计和单元测试跨平台应用程序 [英] Design and unit-test cross-platform application
问题描述
我正在(目前)正在为Windows构建一个项目,并将在将来为darwin构建该项目.
I'm working on a project that builds for windows (currently) and will be built for darwin in future.
以下是快速概述:
file1.go:
package management
type Manager interface {
Action1()
}
file2_windows.go:
file2_windows.go:
package management
type WinManager struct {
some configs
}
func (WinManager) Action1() {
...
}
func InitWinManager() WinManager {
create and return inited WinManager with configs
}
handler.go:
handler.go:
package handle
func handle() {
...
var m Manager
if runtime.GOOS = "windows" {
m = InitWinManager()
}
...
}
问题1:如何针对特定操作系统正确避免Manager的这种有条件初始化?
Q1: How to correctly avoid such conditional initialization of the Manager for specific OS?
关于CI的几句话-由于我们的构建计算机在linux上运行,并且我需要一个.exe文件,因此我将其构建为:
Few words about CI - since our build machine runs on linux and I need an .exe file I build it like that:
- 使用特定于版本的属性和可执行文件的名称创建versioninfo.json 使用
- 运行
GOOS = windows go generate
- 运行
GOOS = windows GOARCH = amd64 go build -o application.exe
//go:generate goversioninfo
在main.go上它的构建还不错,我没有任何麻烦.
It builds just fine and I don't have any troubles with it.
去测试./handle
带来了另一个问题.在运行实际测试之前,它会尝试编译经过测试的程序包,但是由于我的构建计算机的操作系统与Windows不同,因此无法找到 InitWinManager()
方法.
Another problem come up with go test ./handle
. Before running actual test it tries to compile tested package, but it fails to find InitWinManager()
method since my build machine's OS is different from windows.
因此,第二季度:如何在 go test
中指定要运行的操作系统版本?
So Q2: How to specify an OS version to run for in go test
?
推荐答案
将Windows特定于Windows的代码放在file2_windows.go中.此文件仅适用于Windows目标.
Place the Windows specific code in file2_windows.go. This file is built for Windows targets only.
package management
type Manager struct {
... Windows specific type
}
func (Manager) Action1() {
... Windows specific code
}
func InitManager() Manager {
create and return inited Manager with configs
}
将达尔文特定代码放置在file2_darwin.go中.此文件仅适用于达尔文目标.
Place the Darwin specific code in file2_darwin.go. This file is built for Darwin targets only.
package management
type Manager struct {
... Darwin specific type
}
func (Manager) Action1() {
... Darwin specific code
}
func InitManager() Manager {
create and return inited Manager with configs
}
从Handler函数调用InitManager:
Call InitManager from the Handler function:
m := InitManager()
这将在Darwin目标上调用Darwin版本,在Windows目标上调用Windows版本.
This calls the Darwin version on a Darwin target and the Windows version on a Windows target.
以上使用文件名约定来设置构建约束.也可以使用注释指定约束.使用
The above uses the file name convention for setting build constraints. It's also possible to specify the constraints using comments. Use
// +build windows
指定包含文件仅针对Windows目标和
to specify that the containing file is only built for a Windows target and
// +build darwin
指定包含文件仅针对达尔文目标构建.
to specify that the containing file is only built for a Darwin target.
我假设您将Manager定义为Windows和Darwin特定管理器的通用接口.由于一次只在代码中内置一个管理器,因此无需为此定义接口.如果由于其他原因需要该接口,请将上面使用的类型类型更改为ManagerImpl或类似的内容.
I assumed that you defined Manager as a common interface for the Windows and Darwin specific managers. Because only one manager is built into the code at a time, there's no need to define an interface for this purpose. If there's some other reason that the interface is needed, change type types used above to ManagerImpl or something like that.
第二季度:不可能对不同于当前系统的目标系统运行 go test
.
Q2: It's not possible to run go test
for a target system that's different from the current system.
这篇关于设计和单元测试跨平台应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!