Skip to content
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

Results#add(int, List<Result>, List<ResultField>) leads to HTTP 400: "Field :results.test_id is a required field." #43

Open
unix-junkie opened this issue Jul 30, 2019 · 7 comments

Comments

@unix-junkie
Copy link

Whenever I try to bulk-submit test results (via the Results#add(int, List<Result>, List<ResultField>) API), I get:

com.codepine.api.testrail.TestRailException: 400 - Field :results.test_id is a required field.

	at com.codepine.api.testrail.TestRailException$Builder.build(TestRailException.java:57)
	at com.codepine.api.testrail.Request.execute(Request.java:142)

-- most probably the testId field of the newly-created Result object is ignored.

As a workaround, I currently use the Results#addForCases() API.

TestRail version is 6.0.0.4140.

@davidbrazilparker
Copy link

I'm curious, how are you calling the Results.add() method? I don't maintain this project but I have utilized it in the past.

@unix-junkie
Copy link
Author

@davidbrazilparker Thanks for your response David.

First, I've declared the factory method which produces a Result per Test. In Kotlin:

        fun newResult(test: Test,
                              status: Status? = null,
                              assignedtoId: UserId? = null,
                              comment: String? = "Case [C${test.caseId}] completed with status ${status?.label}"): Result = Result().apply {
            testId = test.id
            caseId = test.caseId

            statusId = status?.id
            this.assignedtoId = assignedtoId
            this.comment = comment

            elapsed = "..."
            defects = listOf("foo", "bar")
            version = "..."
        }

Then, I map each Test in a Run to the Result object:

            runs.forEachIndexed { runIndex, run ->
                val tests = run.tests

                val testResults = tests.asSequence().map { test ->
                    newResult(test, status, user.id)
                }.toList()

                // This works
                results.addForCases(run.id, testResults, resultFields).execute()
                // This doesn't
                results.add(run.id, testResults, resultFields).execute()
                }
            }

@davidbrazilparker
Copy link

First of all, Kudos for using Kotlin. It's my go to language now for developing in JVM and overall my preferred language of choice for development in general.

More importantly, I think I found your issue.

Currently you're receiving an error when calling:

results.add(run.id, testResults, resultFields).execute

For the following reason:

/**
         * Adds a new test result, comment or assigns a test.
         * <p>The custom result fields configured in TestRail can be fetched using {@link ResultFields#list()} request.
         * The reason for not fetching this during execution of this request is to allow you to cache the list on your end to prevent an extra call on every execution.</p>
         *
         * @param testId       the ID of the test whose result is to be added
         * @param result       the test result to be added
         * @param resultFields the custom result fields configured in TestRail to get type information for custom fields in the result returned
         * @return the request
         * @throws java.lang.IllegalArgumentException if testId is not positive
         * @throws java.lang.NullPointerException     if any other argument is null
         */
        public Add add(final int testId, @NonNull Result result, @NonNull java.util.List<ResultField> resultFields) {
            checkArgument(testId > 0, "testId should be positive");
            return new Add(testId, result, resultFields);
        }

This is the method you're calling currently. Which only allows for a single result object to be passed in.

The method you're trying to call is the following:

/**
         * Adds one or more new test results, comments or assigns one or more tests.
         * <p>The custom result fields configured in TestRail can be fetched using {@link ResultFields#list()} request.
         * The reason for not fetching this during execution of this request is to allow you to cache the list on your end to prevent an extra call on every execution.</p>
         *
         * @param runId        the ID of the test run to add the results to
         * @param results      the test results to be added
         * @param resultFields the custom result fields configured in TestRail to get type information for custom fields in the results returned
         * @return the request
         * @throws java.lang.IllegalArgumentException if runId is not positive or results is empty
         * @throws java.lang.NullPointerException     if results or resultFields are null
         */
        public AddList add(final int runId, @NonNull java.util.List<Result> results, @NonNull java.util.List<ResultField> resultFields) {
            checkArgument(runId > 0, "runId should be positive");
            checkArgument(!results.isEmpty(), "results cannot be empty");
            return new AddList(runId, results, resultFields);
        }

I don't think this is necessarily something wrong with your code but rather how the .add call is being interpreted. I've encountered weird issues before where I have to explicitly use a Java type rather than a Kotlin type even though they are nearly identical. By this I mean, your .toList call may be the culprit that is causing the wrong .add method to be called and thus causing the error you're receiving.

@davidbrazilparker
Copy link

I'll look into this more when I have time. I am not sure I found the root cause definitively.

@davidbrazilparker
Copy link

davidbrazilparker commented Aug 4, 2019

Working on reproducing your error right now. You can check in on my progress here: https://github.com/chapeco/KotlinTestRailCodepineDebug

Edit - Behavior was reproduced in the repo I shared.

@davidbrazilparker
Copy link

Okay so I think I know what the underlying issue of this particular behavior is. I am confident that it is a bug with how this API client sends the "list" of results.

According to this post on the official Gurock forums - https://discuss.gurock.com/t/add-results-returns-an-error/2414
It is required that the "list" of results be sent to the API as a Map object. Which in this case I'm assuming it is not.

So for now your best bet is to do the workaround you have now as the issue needs to be fixed in this API client.

@unix-junkie
Copy link
Author

@davidbrazilparker Thanks for your investigation David. I will take a closer look in a short while.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants