mobile/app/app_test.go

139 lines
3.2 KiB
Go

// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package app_test
import (
"fmt"
"io/ioutil"
"net"
"os"
"os/exec"
"strings"
"testing"
"time"
"golang.org/x/mobile/app/internal/apptest"
)
// TestAndroidApp tests the lifecycle, event, and window semantics of a
// simple android app.
//
// Beyond testing the app package, the goal is to eventually have
// helper libraries that make tests like these easy to write. Hopefully
// having a user of such a fictional package will help illuminate the way.
func TestAndroidApp(t *testing.T) {
if _, err := exec.Command("which", "adb").CombinedOutput(); err != nil {
t.Skip("command adb not found, skipping")
}
run(t, "gomobile", "version")
origWD, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
tmpdir, err := ioutil.TempDir("", "app-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)
if err := os.Chdir(tmpdir); err != nil {
t.Fatal(err)
}
defer os.Chdir(origWD)
run(t, "gomobile", "install", "golang.org/x/mobile/app/internal/testapp")
ln, err := net.Listen("tcp4", "localhost:0")
if err != nil {
t.Fatal(err)
}
defer ln.Close()
localaddr := fmt.Sprintf("tcp:%d", ln.Addr().(*net.TCPAddr).Port)
t.Logf("local address: %s", localaddr)
exec.Command("adb", "reverse", "--remove", "tcp:"+apptest.Port).Run() // ignore failure
run(t, "adb", "reverse", "tcp:"+apptest.Port, localaddr)
const (
KeycodePower = "26"
KeycodeUnlock = "82"
)
run(t, "adb", "shell", "input", "keyevent", KeycodePower)
run(t, "adb", "shell", "input", "keyevent", KeycodeUnlock)
// start testapp
run(t,
"adb", "shell", "am", "start", "-n",
"org.golang.testapp/org.golang.app.GoNativeActivity",
)
var conn net.Conn
connDone := make(chan struct{})
go func() {
conn, err = ln.Accept()
connDone <- struct{}{}
}()
select {
case <-time.After(5 * time.Second):
t.Fatal("timeout waiting for testapp to dial host")
case <-connDone:
if err != nil {
t.Fatalf("ln.Accept: %v", err)
}
}
defer conn.Close()
comm := &apptest.Comm{
Conn: conn,
Fatalf: t.Fatalf,
Printf: t.Logf,
}
var PixelsPerPt float32
comm.Recv("hello_from_testapp")
comm.Send("hello_from_host")
comm.Recv("lifecycle_visible")
comm.Recv("config", &PixelsPerPt)
if PixelsPerPt < 0.1 {
t.Fatalf("bad PixelsPerPt: %f", PixelsPerPt)
}
comm.Recv("paint")
var x, y int
var ty string
tap(t, 50, 60)
comm.Recv("touch", &ty, &x, &y)
if ty != "begin" || x != 50 || y != 60 {
t.Errorf("want touch begin(50, 60), got %s(%d,%d)", ty, x, y)
}
comm.Recv("touch", &ty, &x, &y)
if ty != "end" || x != 50 || y != 60 {
t.Errorf("want touch end(50, 60), got %s(%d,%d)", ty, x, y)
}
// TODO: screenshot of gl.Clear to test painting
// TODO: lifecycle testing (NOTE: adb shell input keyevent 4 is the back button)
// TODO: orientation testing
}
func tap(t *testing.T, x, y int) {
run(t, "adb", "shell", "input", "tap", fmt.Sprintf("%d", x), fmt.Sprintf("%d", y))
}
func run(t *testing.T, cmdName string, arg ...string) {
cmd := exec.Command(cmdName, arg...)
t.Log(strings.Join(cmd.Args, " "))
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("%s %v: %s", strings.Join(cmd.Args, " "), err, out)
}
}