Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitae00bdf

Browse files
committed
Add simple e2e test
1 parent6fd1b44 commitae00bdf

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed

‎e2e/README.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#E2E Tests
2+
3+
The purpose of the E2E tests is to have a simple (currently) test that gives maintainers some confidence in the black box behavior of our artifacts. It does this by:
4+
* Building the`github-mcp-server` docker image
5+
* Running the image
6+
* Interacting with the server via stdio
7+
* Issuing requests that interact with the live GitHub API
8+
9+
##Running the Tests
10+
11+
Since these tests require a token to interact with real resources on the GitHub API, it is gated behind the`e2e` build flag.
12+
13+
```
14+
GITHUB_MCP_SERVER_E2E_TOKEN=<YOUR TOKEN> go test -v --tags e2e ./e2e
15+
```
16+
17+
The`GITHUB_MCP_SERVER_E2E_TOKEN` environment variable is mapped to`GITHUB_PERSONAL_ACCESS_TOKEN` internally, but separated to avoid accidental reuse of credentials.
18+
19+
##Example
20+
21+
The following diff adjusts the`get_me` tool to return`foobar` as the user login.
22+
23+
```diff
24+
diff --git a/pkg/github/context_tools.go b/pkg/github/context_tools.go
25+
index 1c91d70..ac4ef2b 100644
26+
--- a/pkg/github/context_tools.go
27+
+++ b/pkg/github/context_tools.go
28+
@@ -39,6 +39,8 @@ func GetMe(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mc
29+
return mcp.NewToolResultError(fmt.Sprintf("failed to get user: %s", string(body))), nil
30+
}
31+
32+
+ user.Login = sPtr("foobar")
33+
+
34+
r, err := json.Marshal(user)
35+
if err != nil {
36+
return nil, fmt.Errorf("failed to marshal user: %w", err)
37+
@@ -47,3 +49,7 @@ func GetMe(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mc
38+
return mcp.NewToolResultText(string(r)), nil
39+
}
40+
}
41+
+
42+
+func sPtr(s string) *string {
43+
+ return &s
44+
+}
45+
```
46+
47+
Running the tests:
48+
49+
```
50+
➜ GITHUB_MCP_SERVER_E2E_TOKEN=$(gh auth token) go test -v --tags e2e ./e2e
51+
=== RUN TestE2E
52+
e2e_test.go:92: Building Docker image for e2e tests...
53+
e2e_test.go:36: Starting Stdio MCP client...
54+
=== RUN TestE2E/Initialize
55+
=== RUN TestE2E/CallTool_get_me
56+
e2e_test.go:85:
57+
Error Trace: /Users/williammartin/workspace/github-mcp-server/e2e/e2e_test.go:85
58+
Error: Not equal:
59+
expected: "foobar"
60+
actual : "williammartin"
61+
62+
Diff:
63+
--- Expected
64+
+++ Actual
65+
@@ -1 +1 @@
66+
-foobar
67+
+williammartin
68+
Test: TestE2E/CallTool_get_me
69+
Messages: expected login to match
70+
--- FAIL: TestE2E (1.05s)
71+
--- PASS: TestE2E/Initialize (0.09s)
72+
--- FAIL: TestE2E/CallTool_get_me (0.46s)
73+
FAIL
74+
FAIL github.com/github/github-mcp-server/e2e 1.433s
75+
FAIL
76+
```
77+
78+
##Limitations
79+
80+
The current test suite is intentionally very limited in scope. This is because the maintenance costs on e2e tests tend to increase significantly over time. To read about some challenges with GitHub integration tests, see[go-github integration tests README](https://github.com/google/go-github/blob/5b75aa86dba5cf4af2923afa0938774f37fa0a67/test/README.md). We will expand this suite circumspectly!
81+
82+
Currently, visibility into failures is not particularly good.

‎e2e/e2e_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//go:build e2e
2+
3+
package e2e_test
4+
5+
import (
6+
"context"
7+
"encoding/json"
8+
"os"
9+
"os/exec"
10+
"testing"
11+
"time"
12+
13+
"github.com/google/go-github/v69/github"
14+
mcpClient"github.com/mark3labs/mcp-go/client"
15+
"github.com/mark3labs/mcp-go/mcp"
16+
"github.com/stretchr/testify/require"
17+
)
18+
19+
funcTestE2E(t*testing.T) {
20+
e2eServerToken:=os.Getenv("GITHUB_MCP_SERVER_E2E_TOKEN")
21+
ife2eServerToken=="" {
22+
t.Fatalf("GITHUB_MCP_SERVER_E2E_TOKEN environment variable is not set")
23+
}
24+
25+
// Build the Docker image for the MCP server.
26+
buildDockerImage(t)
27+
28+
t.Setenv("GITHUB_PERSONAL_ACCESS_TOKEN",e2eServerToken)// The MCP Client merges the existing environment.
29+
args:= []string{
30+
"docker",
31+
"run",
32+
"-i",
33+
"--rm",
34+
"-e",
35+
"GITHUB_PERSONAL_ACCESS_TOKEN",
36+
"github/e2e-github-mcp-server",
37+
}
38+
t.Log("Starting Stdio MCP client...")
39+
client,err:=mcpClient.NewStdioMCPClient(args[0], []string{},args[1:]...)
40+
require.NoError(t,err,"expected to create client successfully")
41+
42+
t.Run("Initialize",func(t*testing.T) {
43+
ctx,cancel:=context.WithTimeout(context.Background(),5*time.Second)
44+
defercancel()
45+
46+
request:= mcp.InitializeRequest{}
47+
request.Params.ProtocolVersion="2025-03-26"
48+
request.Params.ClientInfo= mcp.Implementation{
49+
Name:"e2e-test-client",
50+
Version:"0.0.1",
51+
}
52+
53+
result,err:=client.Initialize(ctx,request)
54+
require.NoError(t,err,"expected to initialize successfully")
55+
56+
require.Equal(t,"github-mcp-server",result.ServerInfo.Name)
57+
})
58+
59+
t.Run("CallTool get_me",func(t*testing.T) {
60+
ctx,cancel:=context.WithTimeout(context.Background(),5*time.Second)
61+
defercancel()
62+
63+
// When we call the "get_me" tool
64+
request:= mcp.CallToolRequest{}
65+
request.Params.Name="get_me"
66+
67+
response,err:=client.CallTool(ctx,request)
68+
require.NoError(t,err,"expected to call 'get_me' tool successfully")
69+
70+
require.False(t,response.IsError,"expected result not to be an error")
71+
require.Len(t,response.Content,1,"expected content to have one item")
72+
73+
textContent,ok:=response.Content[0].(mcp.TextContent)
74+
require.True(t,ok,"expected content to be of type TextContent")
75+
76+
vartrimmedContentstruct {
77+
Loginstring`json:"login"`
78+
}
79+
err=json.Unmarshal([]byte(textContent.Text),&trimmedContent)
80+
require.NoError(t,err,"expected to unmarshal text content successfully")
81+
82+
// Then the login in the response should match the login obtained via the same
83+
// token using the GitHub API.
84+
client:=github.NewClient(nil).WithAuthToken(e2eServerToken)
85+
user,_,err:=client.Users.Get(context.Background(),"")
86+
require.NoError(t,err,"expected to get user successfully")
87+
require.Equal(t,trimmedContent.Login,*user.Login,"expected login to match")
88+
})
89+
90+
require.NoError(t,client.Close(),"expected to close client successfully")
91+
}
92+
93+
funcbuildDockerImage(t*testing.T) {
94+
t.Log("Building Docker image for e2e tests...")
95+
96+
cmd:=exec.Command("docker","build","-t","github/e2e-github-mcp-server",".")
97+
cmd.Dir=".."// Run this in the context of the root, where the Dockerfile is located.
98+
output,err:=cmd.CombinedOutput()
99+
require.NoError(t,err,"expected to build Docker image successfully, output: %s",string(output))
100+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp