I'm currently doing server side development for firebase. I'd like to test that my sendMessage function is working by targeting a test token.
I tried using testToken as a value, but arbitrary values will in fact return an error:
Error: The registration token is not a valid FCM registration token
I've searched all over and found no way to test my code without using a phone connected to the service. Am I just missing something?
Does firebase provide any form of test tokens for doing server side development?
If you are working with Android, and don't have a device to test with, you should be able to test against an emulator instance. But you will definitely need to provide FCM a real token that's associated with some device, real or virtual.
This is a very good question, but does some raise further questions.
You want a test token, basically that is mocking, so that will be good for unitary test. But for integrations tests you need to have a real token, so you can test the success case and the error case. So in case of error you can retry or write an entry on the database.
Maybe a better aproach for your test as describe is to mock the method sendMessage or the class containing it. However if you follow this path, please remember, mocking is a double edge sword, you should not mock things dependencies because those are already tested. But mock wrapper components using those dependencies. Off course testing require finese, so maybe mocking one thing aint thar bad.
Related
I am new to PACT and trying to use pact-net for contract testing for a .net microservice. I understand the concept of consumer test which generates a pact file.
There is the concept of a provider state middleware which is responsible for making sure that the provider's state matches the Given() condition in the generated pact.
I am bit confused on the following or how to achieve this:
The provider tests are run against the actual service. So we start the provider service before tests are run. My provider service interacts with a database to store and retrieve records. PACT also mentions that all the dependencies of a service should be stubbed.
So we run the actual provider api that is running against the actual db?
If we running the api against actual db how do we inject the data into the db? Should we be using the provider api's own endpoints to add the Given() data?
If the above is not the correct approach then what is?
All the basic blog articles I have come across do not explain this and usually have examples with no provider states or states that are just some text files on the file system.
Help appreciated.
I'm going to add to Matt's comment, you have three options:
Do your provider test with a connected environment but you will have to do some cleanup manually afterwards and make sure your data is always available in your db or/and the external APIs are always up and running. Simple to write but can be very hard to maintain.
You mock your API calls but call the real database.
You mock all your external dependencies: the API and the DB calls.
For 2) or 3) you will have to have test routes and inject the provider state middleware in your provider test fixture. Then, you can configure provider states to be called to generate in-memory data if solution 3) or add some data-init if you are in solution 2)
You can find an example here: https://github.com/pact-foundation/pact-net/tree/master/Samples/EventApi/Provider.Api.Web.Tests
The provider tests are run against the actual service
Do you mean against a live environment, or the actual service running locally to the unit test (the former is not recommended, because of (2) above).
This is one of the exceptions to that rule. You can choose to use a real DB or an in-memory one - whatever is most convenient. It's common to use docker and tools like that for testing.
In your case, I'd have a specific test-only set of routes that respond to the provider state handler endpoints, that also have access to the repository code and can manipulate state of the system.
I have a Unity3D app backed by a Firebase/Firestore database.
Firebase provides a Local Emulator Suite for testing, but it is not supported on Unity.
It seems the only way to test logic which uses Firestore is to either:
Use a real, test-only database and clear it on each SetUp
Mock out all usages of Firestore
(2) seems error-prone and like I'm reinventing the wheel. (1) seems both dangerous and slow. Is there another widely-supported option I'm missing?
The emulator suite is now supported. See https://github.com/firebase/quickstart-unity/issues/719#issuecomment-938759588
To use the emulator, run
FirebaseFirestore firestore = FirebaseFirestore.DefaultInstance;
firestore.Settings.Host = "localhost:8080";
firestore.Settings.SslEnabled = false;
Make sure you use this code in each assembly used. Many tutorials have the tests run in a separate assembly as the rest of your code. If your architecture is similar, you will need the above code in each assembly. Specifically, be sure to call this code both in your test assembly when accessing FirebaseFirestore.DefaultInstance, and in your game code, since FirebaseFirestore.DefaultInstance exists once per process (i.e. once per assembly).
I have seen some answers to this question using a Java implementation; however, I wasn't able to convert it successfully. The Java implementation seems to use a try, catch approach to determine whether the FirebaseAuthUserCollisionException is ran into or not. But from researching online, it seems try, catch is obsolete in Kotlin.
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email,password)
.addOnCompleteListener(){it:Task<AuthResult>
if(!it.isSuccessful)
This is the only piece of code I have so far. I appreciate all help! Thank you in advance.
try/catch is not obsolete in Kotlin. It still works essentially the same way. It's just not very useful when working with the asynchronous APIs provided by Firebase and Play services.
The Firebase APIs are all asynchronous, so you need to check for errors in the callbacks that you attach to the Task object returned from the call. This is the same for both Java and Kotlin. You might want to learn more about the Task API in order to better deal with Firebase APIs that return a Task to represent asynchronous work. In the code you've shown, you check for errors in an onComplete listener by looking at the exception object in the result if it wasn't successful:
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email,password)
.addOnCompleteListener() { it:Task<AuthResult>
if (!it.isSuccessful) {
val exception = it.exception
// do something with this exception, according to the Firestore API docs
}
We have two micro-services: Provider and Consumer, both are built independently. Consumer micro-service makes a mistake in how it consumes Provider service (for whatever reason) and as a result, incorrect pact is published to the Pact Broker.
Consumer service build is successful (and can go all the way to release!), but next Provider service build will fail for the wrong reason. So we end up with the broken Provider service build and a broken release of Consumer.
What is the best practice to guard against situations like this?
I was hoping that Pact Broker can trigger the Provider tests automatically when contracts are published and notify Consumers if they fail, but it doesn't seem to be the case.
Thanks!
This is the nature of consumer-driven contracts - the consumer gets a significant say in the API!
As a general rule, if the contract doesn't change, there is no need to run the Provider build, albeit there is currently no easy way to know this in the Broker (see feature request https://github.com/bethesque/pact_broker/issues/48).
As for solutions you could use one or more of the below strategies.
Effective use of code branches
It is of course very important that new assumptions on the contract be validated by the Provider before the Consumer can be safely released. Have branches tested against the Provider before you merge into master.
But most importantly - you must be collaborating closely with the Provider team!
Use source control to detect a modified contract:
If you also checked the master pact files into source control, your CI build could conditionally act - if the contract has changed, you must wait for a green provider build, if not you can safely deploy!
Store in separate repository
If you really want the provider to maintain control, you could store contracts in an intermediate repository or file location managed by the provider. I'd recommend this is a last resort as it negates much of the collaboration pact intends to facilitate.
Use Pact Broker Webhooks:
I was hoping that Pact Broker can trigger the Provider tests automatically when contracts are published and notify Consumers if they fail, but it doesn't seem to be the case.
Yes, this is possible using web hooks on the Pact Broker. You could trigger a build on the Provider as soon as a new contract is submitted to the server.
You could envisage this step working with options 1 and 2.
See Using Pact where the Consumer team is different from the Provider team in our FAQ for more on this use case.
You're spot on, that is one of the current things lacking with the Pact workflow and it's something I've been meaning of working towards once a few other things align.
That being said, in the meantime, this isn't solving your current problem, so I'm going to suggest a potential workaround in your process. Instead of running the test for the consumer, them passing, and then releasing it straight away, you could have the test run on the consumer, then wait for the provider test to come back green before releasing the consumer/provider together. Another way would be to version your provider/consumer interactions (api versioning) so that you can release the consumer beforehand, but isn't "turned on" until the correct version of the provider is released.
None of these solutions are great and I wholeheartedly agree. This is something that I'm quite passionate about and will be working on soon to fix the developer experience with pact broker and releasing the consumer/provider in a better fashion.
Any and all comments are welcome. Cheers.
I think the problem might be caused by the fact that contracts are generated on the consumer side. It means that consumers can modify those contracts how they want. But in the end producer's build will suffer due to incorrect contracts generated by consumers.
Is there any way that contracts are defined by producer? As I think the producer is responsible for maintaining its own contracts. For instance, in case of Spring Cloud Contracts it is recommended to have contacts defined in producer sources (e.g. in the same git repo with producer source code) or in a separate scm repo that can be managed by producer and consumer together.
I have the following requirement:
I want to test my UI (using graphene and drone) but I need to login to the application before all tests. I have a Database authentication Realm in jboss which for testing uses an H2 in-memory database. So what I need is to add a user (username, password) before all tests in the users table so I can login successfully in my application.
I first tried to inject my users EJB in the test class so I can create a user before all tests in the database. This is impossible because the UI tests run on the client (testable=false). It was obvious that at the time I did not know exactly how arquillian works...
I then tried to use arquillian persistence extension and #UsingDataSet annotation but this also fails for the same reason (although I am not sure why, since I don't know exactly how this annotation works).
Finally, I tried to create a Singleton EJB with #Startup annotation and on its #PostConstruct method create the user I need. When debugging, I can see in the H2 console that the user is created. But when I run my tests the login still fails.
Can someone explain why this last case fails because I do not understand. But most importently if someone knows how to make this work I would greately appreciate it!
So, when you run a client side test nothing gets added to your archive. If it's possible for you, mark your archive as testable=true and then these extensions will be added to the test. Your can do things like have a setup method that runs on the server, however the values for the user will not be sent you. You'll need to insert them. As long as you're ok with that need this should work for you.