Functional tests using PHPUnit - unit-testing

I see WebTestCase and Symfony come up a lot...I have some unit tests in PHPUnit already but really need higher level tests...I do not need anything fancy like Selenium (the UI is done in ExtJS but this could change entirely to Polymer in the future) I just need to post data and check the JSON results.
Can this be done via PHPUnit or do I need to bring in Symfony and it's WebTestCase?
Testing RESTful web services using PHPUnit
Note: I am actually looking to test the services -- no mocked objects desired -- I need to login when the test suite is first run -- store the SESSION ID and go through each test...

I have achieved success in writing PHP functional tests using Guzzle.
It allows you to perform HTTP requests like this:
$client = new GuzzleHttp\Client();
$response = $client->get('http://guzzlephp.org');
And the $client will maintain the PHPSESSIONID across requests, allowing you to perform authenticated requests by logging in and then performing requests with the same client.

Related

What are the best practices for testing a FastAPI project with JWT authentication?

I have FastAPI project which does the following:
Register users(unauthenticated)
CRUD operations on user resources(authenticated)
What I want to do:
Develop an automated testing framework to unit test all the APIs
Run that on a devops platform like jenkins regularly
Run it locally before deployment
Some specific doubts I have:
For testing, should I use the OpenAPI generated client sdk or the FastAPI client or use the python requests module?
Authentication should happen only once and reuse the JWT token or fresh authentication for each API test ?
Should I use the same pydantic modules for dev and testing or re-write them to ensure that no issues were introduced in case of updated models ?
How to do proper unit testing when one API requires result from multiple other APIs?
Use the built-in TestClient
Use a fixture and let pytest sort it out for you; if it's too slow to reauthenticate each time, change the scope of the fixture to a larger scope (i.e. class, module, session, etc.). You can also use FastAPI's dependency_overrides to let your tests run with static authentication configured (so that you can skip actually authenticating in most of your tests).
You should test what you use in your application. Nothing specific written for your tests, except if necessary to make your application testable in a better way.
The only "proper" thing is that your API has been tested to work as you expect it to work. Do multiple API calls if necessary, but move them into fixtures to get composable sets of dependencies for tests (i.e. the result of the fixture can be cached and re-used for all tests in a test class if necessary). If you have tests that depend on a customer being created, create a fixture that creates a customer and use that fixture in the tests where a created customer is necessary.

Can a web service client with identical signature call a different web service?

My project has gotten into web services lately, but our QA team has a request to be able to set up a clone client and clone web service so that they can issue a request from the clone client to the real web service and from the real client to the clone service to test the real pieces individually.
The clone client to real web service part is easy, I just wrap the generated client in a main() app that picks up data to send that the test team specifies. But the service part is confusing to me. How can I make a dummy service that just echoes out its requests to a log without affecting the real service? I want the real client to use the same generated client code, just point the soft-coded URL to the URL of the dummy.
If I define a new web service with identical names and signatures to the real service, can the real client hit the dummy with just a URL change? Or is it more complicated? Am I barking up the wrong tree?
Re: Making a dummy service
This would actually be called making a "mock" service or a web service "stub". You don't even technically have to code it - you can use tools. For example, SoapUI has the ability to import a WSDL and create a mock service. The have some other discussion of mock services as well - they can be used both to test the client application (or to simply develop it before the back-end resources are ready or available). To use a WSDL-based service stub you would simply change the endpoint of your client-under-test to the stub instance. SoapUI will show you (and let you configure) the stub's endpoint URL.
The trendy term for service mocking and stubbing is "service virtualization" (not to be confused with server virtualization as in virtual machines). Searches using this terminology will find you even more powerful (and expensive) tooling.
Re: Just a URL Change
Yep, for the most part. So long as the XML namespaces are the same and the WSDL is the same (minus endpoint URL) you should be fine. Since the WSDL acts as an interface contract, the stub MUST accept those same inputs and produce those same outputs. How it does so, of course, is up to you.
PS - free extra advice - Don't code a dummy client. Use tools (I'll use SoapUI again as an example free tool) to make your web service testing more robust and repeatable. You can create test suites with sample SOAP requests, add assertions on how the service should behave, and best of all - your investment in time of creating a test project can be shared across team members, cutting down time to test setup and making sure testing is thorough and repeatable. If you code a client, every tester/user of the test client will have their own way of testing, response inspection will probably be manual, and you'll notice when your best QA tester goes on vacation because regressions slip into the web service product. Repeatable testing can nix this, and tool based automated functional testing is the bees knees. You're already on the right path by testing the pieces individually.

How to unit test my Google OpenID consumer app?

My web app is a Google OpenID consumer (with Attribute Exchange and OAuth Extension) and I need to write some unit test for it [edit: to test the unit that is responsible to interact with google].
The problem is that default OpenID login procedure needs user interaction (entering user/pass) which is not possible in unit test.
Do you have any idea how can I solve this problem and unit test my OpenID consumer app?
(I prefer not to run my own OpenID provider.)
You need to use a remote controlled browser for this. Selenium was made for this use case.
(indeed they are called functional tests then).
Search on Google for the best way to integrate selenium tests into your web framework.
If I understand you want to test your all application and not just "unit test" it.
The actual test framework depends on the technology your application is using. For example there are many UI and web automation tools that can do what you want.
You should also unit test your core functionality or at least write several integration tests that work against an actual Openid provider but instead of running the entire application just test the functionality of the class (if you're using language that has classes) to make sure it can get the b.
I would also write a couple of unit tests that call a fake provider to test how your code behaves in case of error, connection problems and plain vanilla responses.

Selenium - can it test a B2B web service

I've used Selenium to do lots of UI testing from the browser. If you have a web service behind the Java jsp page i.e. in a servlet, you can test it from Selenium.
Can Selenium be used to test a B2B web service i.e. a web service called from a backend that has no browser UI component?
I have used SOAPUI to do this kind of testing in the past but our test department is trying to standardise on Selenium.
You can but I would not recommend it. If the page is returning XML, you won't be able to use the standard Selenium calls to verify what is happening as you won't have access to the DOM. If its returning plain text for JavaScript then you will struggle with verifying the output.
This is a definite case of using the right tool for the job and Selenium is not the right tool for testing web services. I would use soapUI or just use some http library to call the service URL and then verify the results.
If they are looking to standardise they need to standardise tools for their purpose. Selenium for UI, soapUI for webservices,XUnit Framework for unit and integration.
You can, but it's really not the right tool for the job. It's like trying to hammer a nail into a piece of wood using a stapler instead of a hammer.
That said, probably the most appropriate way to create a page with all your input parameters which could do the call for you and echo the results back into a html element. If the service is meant for AJAX calls then this is probably the ideal solution for your service.
The correct approach would be to use a unit testing framework and create a test harness which you can push your parameters into, execute the service call and retrieve the results in a meaningful way for assertion.

How to unit test your API?

I'm at the point where I need to write unit tests for a REST API written using CakePHP 1.3. The API supports GET, POST and PUT requests for querying and manipulating data.
Is there any established way to test the correct input/output of an API simulating an HTTP request, using fixtures? I do not want to run actual POST/PUT requests against the live (dev) database. How can I best mock out the system to use temporary models, yet test the rest of the stack as-is?
Testing GET requests is easy enough with controller tests. However, for data manipulation the API uses HTTP headers quite extensively and also parses raw XML and JSON POST/PUT data. The controller unit test methods only mock POST data by setting $this->data in the controller, which does not allow me to properly test the API.
You should either create Mocks or use Isolation Framework in order to simulate API environment. Unit tests should not depend on resources like internet connections, network, endpoints etc.
If you intend to test real API calls you should create integration test project and use it for this purpose. But be aware integration tests are mostly not repeatable and would give you different results on each run.
I'd recommend starting with a little research. These articles should help:
Unit Testing CakePHP Shells
Testing CakePHP controllers - Mock Objects edition
Testing Models with CakePHP 1.2 test suite
Looks like you might be able to test the raw XML PUT and POST data without too much trouble. The CakePHP REST documentation says this:
If a POST or PUT request has an XML content-type, then the input is taken and passed to an instance of Cake's Xml object, which is assigned to the $data property of the controller. Because of this feature, handling XML and POST data in parallel is seamless: no changes are required to the controller or model code. Everything you need should end up in $this->data.
Try stepping through your controller code in debug mode to see what actually comes in through $this->data during an XML request.
As for avoiding the live database, would a SQLite in-memory database be any easier?