DEV Community

Discussion on: Java vs Go: Impressive solutions for invented problems

Collapse
 
jawher profile image
Jawher Moussa

Hi John and thank you for the kind words.

In junit the parameters can be shared with any test. This way you can test multiple aspects with the same data.

Right !
To achieve the same using the host language's constructs, you could:

1. define a package-level variable with the various cases:

type loginCase struct {
    Username string
    Password string
    Expected bool
}

var (
    staticLoginCases = []loginCase{
        {"username", "p@$$w0rd", true},
        {"incorrect-username", "p@$$w0rd", false},
        {"username", "incorrect-p@$$w0rd", false},
    }
)

func TestLogin(t *testing.T) {
    for _, tt := range staticLoginCases {
        t.Run(fmt.Sprintf("login(%s, %s) => %v", tt.Username, tt.Password, tt.Expected), func(t *testing.T) {
            require.Equal(t, tt.Expected, login(tt.Username, tt.Password))
        })
    }
}

func TestAnotherLoginFeature(t *testing.T) {
    for _, tt := range staticLoginCases {
        t.Run(fmt.Sprintf("another test(%s, %s) => %v", tt.Username, tt.Password, tt.Expected), func(t *testing.T) {
            require.Equal(t, tt.Expected, login(tt.Username, tt.Password))
        })
    }
}

2. generate the test cases from a function

type loginCase struct {
    Username string
    Password string
    Expected bool
}

func generateLoginCases() []loginCase {
    var res []loginCase

    res = append(res, loginCase{"username", "p@$$w0rd", true})

    for i := 0; i < 500; i++ {
        res = append(res, loginCase{fmt.Sprintf("user#%d", i), "p@$$w0rd", false})
    }

    return res
}

func TestLogin(t *testing.T) {
    for _, tt := range generateLoginCases() {
        t.Run(fmt.Sprintf("login(%s, %s) => %v", tt.Username, tt.Password, tt.Expected), func(t *testing.T) {
            require.Equal(t, tt.Expected, login(tt.Username, tt.Password))
        })
    }
}

func TestAnotherLoginFeature(t *testing.T) {
    for _, tt := range generateLoginCases() {
        t.Run(fmt.Sprintf("another test(%s, %s) => %v", tt.Username, tt.Password, tt.Expected), func(t *testing.T) {
            require.Equal(t, tt.Expected, login(tt.Username, tt.Password))
        })
    }
}

3. load the test cases from a JSON/Yaml/CSV/.. file

Again, you have the full standard library to achieve whatever you need :)

Collapse
 
moaxcp profile image
John Mercier

Yes! I think the same style could also be done in junit but it probably wouldn't pass a review. I do think that junit provides some nice ways to remove verbose code and just declare the parameters you want in the test. In some cases it is probably just better not to use it though. It depends on how common the code is and how much time is saves.

In graphs I was able to take advantage of these features in junit here, for example, but it is not for everyone.