-
Notifications
You must be signed in to change notification settings - Fork 243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add unit test doc #612
Add unit test doc #612
Conversation
817f1b8
to
0336400
Compare
docs/development.md
Outdated
#### Unit test for functions consuming client-go functions | ||
|
||
We started writing unit-tests for the functions which are making API calls with client-go library | ||
by using package fake[ ref: https://godoc.org/k8s.io/client-go/kubernetes/fake ]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we put links in markdown format instead?
docs/development.md
Outdated
We started writing unit-tests for the functions which are making API calls with client-go library | ||
by using package fake[ ref: https://godoc.org/k8s.io/client-go/kubernetes/fake ]. | ||
|
||
There are few techniques we are using for mocking the api calls, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the tense for the entire document should be simple present tense.
docs/development.md
Outdated
by using package fake[ ref: https://godoc.org/k8s.io/client-go/kubernetes/fake ]. | ||
|
||
There are few techniques we are using for mocking the api calls, | ||
basically mocking the actual api calls with functions defined in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove basically
docs/development.md
Outdated
from there and using https://golang.org/pkg/testing/ for tests. | ||
|
||
|
||
##### How to write unit tests having API calls in a nutshell? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just "Writing unit tests" should be fine ...
docs/development.md
Outdated
|
||
##### How to write unit tests having API calls in a nutshell? | ||
|
||
- Identify the API calls being made by the function during the execution |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to have example code for each of these points.
Also, bullet/number them.
docs/development.md
Outdated
adding reactors for the relevent actions is the way to go with this situation. | ||
|
||
for example take a look at `RemoveVolumeFromDeploymentConfig` | ||
https://github.com/redhat-developer/odo/blob/master/pkg/occlient/occlient.go#L1413 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use [](url)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thought explicit will be better but will go with hyperlink
docs/development.md
Outdated
} | ||
``` | ||
|
||
so for this we can add a reactor like below, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think instead of using RemoveVolumeFromDeploymentConfig
which internally calls GetDeploymentConfigFromName
, we should have examples of functions which directly make create
, list
and get
calls.
docs/development.md
Outdated
return true, tt.dcBefore, nil | ||
}) | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need more description for this section explaining the concepts like reactor
, actions
, verb
in more detail. We could work together on this.
Add unit test documentation into development.md
What'st he status of this @syamgk ? |
@cdrage incorporated the comments and ready for next round of review |
docs/development.md
Outdated
#### Unit test for functions consuming client-go functions | ||
|
||
Unit-tests for the functions making API calls with client-go library | ||
can be written by using package (fake)[https://godoc.org/k8s.io/client-go/kubernetes/fake]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
convert fake itself into a clickable link as in https://github.com/redhat-developer/odo/pull/673/files#diff-6fede6782d33a3306a99cb1a47ea5f6bR23
docs/development.md
Outdated
can be written by using package (fake)[https://godoc.org/k8s.io/client-go/kubernetes/fake]. | ||
|
||
The way to mock the api calls is by mocking the actual api calls with functions defined in | ||
(client-go/testing)[https://godoc.org/k8s.io/client-go/testing] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
docs/development.md
Outdated
} | ||
``` | ||
|
||
Looking at the function body and identify how many API calls it is making while execution. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be observed that, the function CreateRoute above is making 1 api call as in the line below:
r, err := c.routeClient.Routes(c.namespace).Create(route)
docs/development.md
Outdated
r, err := c.routeClient.Routes(c.namespace).Create(route) | ||
``` | ||
|
||
for example, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be ok to shorten the description as under:
From the API call extract above, it is clear that the routeClient needs to be mocked.
The mock routeClient can be obtained using pkg/occlient/fakeclient.go#FakeNew function.
It is done as under:
code here...
Note:
The FakeNew function contains mock implementations of all client sets currently in use by Odo
If the mock implementation of a client set that you are using does not exist, please add it as under:
fkclientset.RouteClientset = fakeRouteClientset.NewSimpleClientset()
client.routeClient = fkclientset.RouteClientset.Route()
docs/development.md
Outdated
and the number of actions performed on routeclientset. | ||
|
||
|
||
Then after making that function call inside the test function, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideal list of items to validate in the unit test function are:
- Number of actions performed or number of api calls made using the client set
ex :len(fkclientset.RouteClientset.Actions())
- Validate the return values of the function being tested
ex: here
docs/development.md
Outdated
and values are being validated later. | ||
Ref. (here)[https://github.com/redhat-developer/odo/pull/456/files#diff-54c1e3725d2cfb565cbd1cfdb02bd792R63] | ||
|
||
For the API calls which are returning objects that are later being processed inside the function body, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this above I feel it would be nice if we could group all mocking together, all validations together etc..
and would it be nice to rephrase it as under:
Mock the api call return values using reactor functions here
docs/development.md
Outdated
For the API calls which are returning objects that are later being processed inside the function body, | ||
adding reactors for the relevent actions is also needed. | ||
|
||
for example take a look at `GetDeploymentConfigsFromSelector` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nice to convert all(as much as possible) all github links to markdown links and not expose the github urls(Github urls seem very ugly to me from the perspective of a reader :) but yes this for a special reader -- A DEVELOPER :P but still I feel it would be nice to avoid it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible can we pick one single example that covers all aspects of testing and only consider that throughout the doc?
Not a very crucial thing to be done, but I feel it would avoid context switches in reader's mind
docs/development.md
Outdated
|
||
More examples can be found in https://github.com/redhat-developer/odo/blob/master/pkg/occlient/occlient_test.go | ||
|
||
- Reactor is an interface to allow the composition of reaction functions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be call this section as Terminologies or something?
Unit testsIntroductionUnit-tests for ODO functions are written using package fake. This allows us to create a fake client, and then mock the API calls defined under OpenShift client-go and k8s client-go. The tests are written in golang using (pkg/testing)[https://golang.org/pkg/testing/] package. Writing unit tests
Initialising fake client and creating fake objectsLet us understand the initialisation of fake clients and thereafter creation of fake objects with an example. The function
The You can see the entire test function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ODO needs to be Odo.
docs/development.md
Outdated
|
||
##### Introduction | ||
|
||
Unit-tests for ODO functions are written using package [fake](https://godoc.org/k8s.io/client-go/kubernetes/fake). This allows us to create a fake client, and then mock the API calls defined under [OpenShift client-go](https://github.com/openshift/client-go) and [k8s client-go](https://godoc.org/k8s.io/client-go). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ODO needs to be Odo.
docs/development.md
Outdated
|
||
Unit-tests for ODO functions are written using package [fake](https://godoc.org/k8s.io/client-go/kubernetes/fake). This allows us to create a fake client, and then mock the API calls defined under [OpenShift client-go](https://github.com/openshift/client-go) and [k8s client-go](https://godoc.org/k8s.io/client-go). | ||
|
||
The tests are written in golang using [pkg/testing](https://golang.org/pkg/testing/) package. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using the
docs/development.md
Outdated
|
||
##### Initialising fake client and creating fake objects | ||
|
||
Let us understand the initialisation of fake clients and thereafter creation of fake objects with an example. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
therefore the creation of fake objects with an example.
docs/development.md
Outdated
|
||
The function `GetImageStreams` in [pkg/occlient.go](https://github.com/redhat-developer/odo/blob/master/pkg/occlient/occlient.go) fetches imagestream objects through the API: | ||
|
||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you need to make it:
```go
wherever there is go code to be shown.
docs/development.md
Outdated
|
||
2. In the `GetImageStreams` funtions, the list of imagestreams is fetched through the API. While using fake client, this list can be emulated using a [`PrependReactor`](https://github.com/kubernetes/client-go/blob/master/testing/fake.go) interface: | ||
|
||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
```go
docs/development.md
Outdated
}) | ||
``` | ||
|
||
The `PrependReactor` expects `resource` and `verb` to be passed as arguments. We can get this information by looking into [`List` function for fake imagestream](https://github.com/openshift/client-go/blob/master/image/clientset/versioned/typed/image/v1/fake/fake_imagestream.go): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
passed in as arguments
docs/development.md
Outdated
}) | ||
``` | ||
|
||
The `PrependReactor` expects `resource` and `verb` to be passed as arguments. We can get this information by looking into [`List` function for fake imagestream](https://github.com/openshift/client-go/blob/master/image/clientset/versioned/typed/image/v1/fake/fake_imagestream.go): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by looking at the
docs/development.md
Outdated
The `PrependReactor` expects `resource` and `verb` to be passed as arguments. We can get this information by looking into [`List` function for fake imagestream](https://github.com/openshift/client-go/blob/master/image/clientset/versioned/typed/image/v1/fake/fake_imagestream.go): | ||
|
||
|
||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
```go
docs/development.md
Outdated
action.ListRestrictions = ListRestrictions{labelSelector, fieldSelector} | ||
|
||
return action | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you forgot to end this with 3 `
docs/development.md
Outdated
} | ||
|
||
|
||
The `List` function internally calls `NewListAction` defined in [k8s.io/client-go/testing/actions.go](https://github.com/kubernetes/client-go/blob/master/testing/actions.go). From these functions, we see that the `resource` and `verb`to be passed into the `PrependReactor` interface are `imagestreams` and `list` respectively. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
space after verb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interface are imagestreams
and list
functions.
This LGTM 👍 I'm going to merge this in. (only 1 ACK needed for docs) |
* Add unit test doc into development.md Add unit test documentation into development.md * incorporated changes as per anush's review * patched with anush's modification * incorporated cdrage's comments
Add Unit test documentation to deployment.md