Testing a package that has a main function in it

6,502 views
Skip to first unread message

Fumin Wang

unread,
Aug 28, 2013, 9:16:59 AM8/28/13
to golan...@googlegroups.com
Assuming we're in $GOPATH/src/geochat

geocoding.go
------------------
package geochat
func SomeFunction() {
}

geocoding_test.go
------------------------
package geochat
import "testing"
func TestSomeFunction(t *testing.T) {
  // Test it
}

$ go test # Works!
PASS
ok    geochat 0.019s

but adding an addition file in the same folder

geochat.go
---------------
package main
func main() {
}

returns an absurd error:
can't load package: package geochat: found packages geochat (geocoding.go) and main (main.go) in $GOPATH/src/geochat

Renaming geochat.go to main.go and adding a dummy file doesn't help either

geochat.go
--------------
package geochat
// Empty content

Can't imagine why this is so ridiculously difficult in golang?! Really going nuts!

chris dollin

unread,
Aug 28, 2013, 9:20:49 AM8/28/13
to Fumin Wang, golang-nuts
All the files in a single directory must belong to the same package.

(And all the files of a package must be in a single directory.)

Chris


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Chris "allusive" Dollin

Fumin Wang

unread,
Aug 28, 2013, 9:26:52 AM8/28/13
to golan...@googlegroups.com, Fumin Wang, ehog....@googlemail.com
But then where should we place the file that contains the main function using this package?

Supplying more context, I'm following the net/http tutorial whose code surely needs a main package. In this case, how do have both a main package and write tests for it at the same time?

Jan Mercl

unread,
Aug 28, 2013, 9:31:48 AM8/28/13
to Fumin Wang, golang-nuts, chris dollin
On Wed, Aug 28, 2013 at 3:26 PM, Fumin Wang <awaw...@gmail.com> wrote:
> But then where should we place the file that contains the main function
> using this package?

in package main.

---- main.go
package main

func foo() string { return "bar" }

func main() { println(foo()) }
---- foo_test.go
package main

import "testing"

func Test(t *testing.T) {
if g, e := foo(), "bar"; g != e {
t.Fatal(g, e)
}
}
----

-j

> On Wednesday, 28 August 2013 21:20:49 UTC+8, chris dollin wrote:
>>
>> All the files in a single directory must belong to the same package.

Except for test files which can be in their own distinct package.

-j

Hotei

unread,
Aug 28, 2013, 9:37:58 AM8/28/13
to golan...@googlegroups.com, Fumin Wang, ehog....@googlemail.com
Use a different directory for each main().  That's "generally speaking" how packages work.  Multiple different mains() will import your package (usually) and each one will require you to create a different directory.  If you only require one main(), you don't need to make it a package.

chris dollin

unread,
Aug 28, 2013, 9:46:04 AM8/28/13
to Fumin Wang, golang-nuts
On 28 August 2013 14:26, Fumin Wang <awaw...@gmail.com> wrote:
But then where should we place the file that contains the main function using this package?

Somewhere else, as part of package main.
 
Chris

--
Chris "allusive" Dollin

Fumin Wang

unread,
Aug 28, 2013, 9:48:05 AM8/28/13
to golan...@googlegroups.com, Fumin Wang, ehog....@googlemail.com
@Jan, I'm afraid that doesn't work, "go test" stubbornly complains with

can't load package: package geochat: found packages geochat (geocoding.go) and main (main.go) in $GOPATH/src/geochat

@Hotei, that's possible, but I find it disturbing due to the fact that in order for me to deploy the web app, I need to do two git commits and pushes which is cumbersome. Is there a more convenient and robust way out?

I have a feeling that the crux of the problem is with the "go test" command itself. Does anyone else share the same feeling as I do?

chris dollin

unread,
Aug 28, 2013, 9:48:34 AM8/28/13
to Jan Mercl, Fumin Wang, golang-nuts
 
> On Wednesday, 28 August 2013 21:20:49 UTC+8, chris dollin wrote:
>>
>> All the files in a single directory must belong to the same package.

Except for test files which can be in their own distinct package.

Yes, I had forgotten that; it allows you to write tests that can't see
the insides of the package.

Chris

--
Chris "allusive" DollinJan wrote:

Jan Mercl

unread,
Aug 28, 2013, 9:55:40 AM8/28/13
to Fumin Wang, golang-nuts, chris dollin
On Wed, Aug 28, 2013 at 3:48 PM, Fumin Wang <awaw...@gmail.com> wrote:
> @Jan, I'm afraid that doesn't work, "go test" stubbornly complains with
>
> can't load package: package geochat: found packages geochat (geocoding.go)
> and main (main.go) in $GOPATH/src/geochat

_______________________________________________________________________________
(15:53) jnml@fsc-r550:~/src/tmp/x$ ll
celkem 8
-rw-rw-r-- 1 jnml jnml 114 srp 28 15:53 foo_test.go
-rw-rw-r-- 1 jnml jnml 81 srp 28 15:53 main.go
_______________________________________________________________________________
(15:53) jnml@fsc-r550:~/src/tmp/x$ cat foo_test.go
package main

import "testing"

func Test(t *testing.T) {
if g, e := foo(), "bar"; g != e {
t.Fatal(g, e)
}
}
_______________________________________________________________________________
(15:53) jnml@fsc-r550:~/src/tmp/x$ cat main.go
package main

func foo() string { return "bar" }

func main() { println(foo()) }
_______________________________________________________________________________
(15:53) jnml@fsc-r550:~/src/tmp/x$ go test -v
=== RUN Test
--- PASS: Test (0.00 seconds)
PASS
ok tmp/x 0.007s
_______________________________________________________________________________
(15:54) jnml@fsc-r550:~/src/tmp/x$

-j

Fumin Wang

unread,
Aug 28, 2013, 10:06:35 AM8/28/13
to golan...@googlegroups.com, Fumin Wang, chris dollin
@Jan, thanks, I know I can test functions in package main, but my problem is the inability to test functions of package geochat.

@Chris, about tests enjoying the privilege of having arbitrary package names, I tried renaming the package from geochat to geochat_test like many of the standard libraries do including net/http, but to no avail.

It seems that according to Hotei and Chris's opinion, the only is to move package main out of the folder.
Nevertheless, since I surely want a main package to be in the same git repo and thus folder, I'm thinking of having a stupid yet necessary script that
* moves geochat.go out of the folder
* runs "go test"
* and moves geochat.go back to the folder

Folks out there using Golang in the wild building web apps, I'm really curious do you really place package main in some separate folder in a separate git repo or is there actually smarter way out?

Jan Mercl

unread,
Aug 28, 2013, 10:14:18 AM8/28/13
to Fumin Wang, golang-nuts, chris dollin
On Wed, Aug 28, 2013 at 4:06 PM, Fumin Wang <awaw...@gmail.com> wrote:
> Folks out there using Golang in the wild building web apps, I'm really
> curious do you really place package main in some separate folder in a
> separate git repo or is there actually smarter way out?

$GOPATH/src/github.com/joe/foo
main.go // go-gettable command: '$ go get github.com/joe/foo',
it imports bar using 'import "github.com/joe/foo/bar"'
all_test.go
$GOPATH/src/github.com/joe/foo/bar
bar.go // package bar
all_test.go

Repository root is $GOPATH/src/github.com/joe/foo.

-j

Peter Kleiweg

unread,
Aug 28, 2013, 10:16:49 AM8/28/13
to golan...@googlegroups.com, Fumin Wang, chris dollin
Op woensdag 28 augustus 2013 15:31:48 UTC+2 schreef Jan Mercl:
I just tried.  That doesn't work. Test files must be the same package as the rest of the files.

chris dollin

unread,
Aug 28, 2013, 10:19:53 AM8/28/13
to Fumin Wang, golang-nuts
On 28 August 2013 15:06, Fumin Wang <awaw...@gmail.com> wrote:
@Jan, thanks, I know I can test functions in package main, but my problem is the inability to test functions of package geochat.

I think that's because you have files from separate packages in
your geochat directory.
 
@Chris, about tests enjoying the privilege of having arbitrary package names,

Not arbitrary. Ending in _test .

| I tried renaming the package from geochat to geochat_test like
| many of the standard libraries do including net/http, but to no avail.

See above.


It seems that according to Hotei and Chris's opinion, the only is to move package main out of the folder.

Yes. That is the Go way, the way the tools expect your source to be
laid out. Packages correspond to directories.

| Nevertheless, since I surely want a main package to be in the
| same git repo and thus folder,

No? It can be in the same repository but in a different
directory.


| I'm thinking of having a stupid yet necessary script that
| * moves geochat.go out of the folder
| * runs "go test"
| * and moves geochat.go back to the folder

You don't need to mess around like that at all.

| Folks out there using Golang in the wild building web apps, I'm
| really curious do you really place package main in some separate
| folder in a separate git repo or is there actually smarter way out?

Same repo, different folder.

http://golang.org/doc/code.html

Jan Mercl

unread,
Aug 28, 2013, 10:26:06 AM8/28/13
to Peter Kleiweg, golang-nuts, Fumin Wang, chris dollin
On Wed, Aug 28, 2013 at 4:16 PM, Peter Kleiweg <pkle...@xs4all.nl> wrote:
>> Except for test files which can be in their own distinct package.
>
> I just tried. That doesn't work. Test files must be the same package as the
> rest of the files.

Try again ;-)

https://code.google.com/p/go/source/browse/src/pkg/fmt/fmt_test.go

-j

atomly

unread,
Aug 28, 2013, 11:06:56 AM8/28/13
to golang-nuts
Why can't geochat.go be in package geochat?

:: atomly ::

[ ato...@atomly.com : www.atomly.com  : http://blog.atomly.com/ ...
[ atomiq records : new york city : +1.347.692.8661 ...
[ e-mail atomly-new...@atomly.com for atomly info and updates ...


--

Kiki Sugiaman

unread,
Aug 28, 2013, 12:03:45 PM8/28/13
to golan...@googlegroups.com
Because the file containing main() has to be in package main?

Kiki Sugiaman

unread,
Aug 28, 2013, 12:21:21 PM8/28/13
to golan...@googlegroups.com
A few quick rules:
- You can have many files in the same folder, but they all have to belong to a single package.
- Assuming your code is an app and not a library (it is meant to execute as opposed to being called from another package), the file containing main() has to be in package main, in its own folder. It is the entry point of your entire app.
- If you want to group everything into one package, the package name has to be main (I know you probably want to call your package "package xyz", but in this case you can't).
- If you want a part of your code to be used as a library to your app, put them in a separate folder. You can then call that part "package xyz".
Reply all
Reply to author
Forward
0 new messages