I can't able to store snapshot.data to database via floor in Flutter. I wrote entity, dao and database file, builded database and database.g.dart succesed to complete, but when I tried to insertUser function it turns below error;
What am I missing? Is there anything to do for record future snapshot.data which there isn't in [the guide]?1
Error:
════════ Exception caught by gesture ═══════════════════════════════════════════════════════════════
The following NoSuchMethodError was thrown while handling a gesture:
The method 'insertUser' was called on null.
Receiver: null
Tried calling: insertUser(Instance of 'UserF')
My entity:
import 'package:floor/floor.dart';
#entity
class UserF {
#PrimaryKey(autoGenerate: true)
final int id;
final String user;
final int overview;
UserF({this.id,
this.user,
this.overview,
#override
int get hashCode => id.hashCode ^ user.hashCode ^ overview.hashCode ;
#override
String toString() {
return 'UserF{id: $id, user: $user, overview: $overview}';
}
}
DAO:
import 'package:floor/floor.dart';
import 'entity.dart';
#dao
abstract class UserDao {
#Query('SELECT * FROM UserF')
Future<List<UserF>> findAllUsers();
#Query('SELECT * FROM UserF WHERE id = :id')
Stream<UserF> findUserById(int id);
#insert
Future<void> insertUser(UserF userF);
#delete
Future<int> deleteUser(UserF userF);
}
Database:
import 'dart:async';
import 'package:floor/floor.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart' as sqflite;
import 'user_dao.dart';
import 'entity.dart';
part 'database.g.dart'; // the generated code will be there
#Database(version: 1, entities: [UserF])
abstract class AppDatabase extends FloorDatabase {
UserDao get userDao;
}
Related Parts on my main.dart
Future<void> main() async{
WidgetsFlutterBinding.ensureInitialized();
final AppDatabase = await $FloorAppDatabase
.databaseBuilder('database.db')
.build();
runApp(MyApp());
}
....
floatingActionButton: FloatingActionButton(
onPressed: (){
final userf = UserF(user: snapshot.data.user, overview: snapshot.data.overview);
favoriteDao.insertUser(userf);
},
child: Icon(Icons.add),
....
If the code :
part 'database.g.dart';
is creating error that means you have to generate that file.
Add these dependencies if you haven't already:
Dependencies:
floor: ^0.14.0
sqflite: ^1.3.0
Dev Dependencies:
floor_generator: ^0.14.0
build_runner: ^1.8.1
In terminal run the following command:
flutter packages pub run build_runner build
And wait for some time. Flutter will generate the command.
Flutter will automatically generate the file.
REMEMBER: THE NAME OF THE DATABASE FILE AND NAME OF GENERATED FILE MUST BE SAME EXEPT FOR ADDING .g
For Example
if the database file name is mydatabase.dart
the generated file name must be mydatabase.g.dart
Related
I'm facing a problem which I cannot seem to resolve.
I have an entity which has a property (specifically a string) with a value of 'In magazijn':
package com.Code.Pakket.management.model;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.jpa.repository.Modifying;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
//Men maakt een JPA entity class zodat hibernate met onze data kan werken.
#Entity
public class Pakketje {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private int code;
private String status ="In magazijn";
public Pakketje() {
}
I would like this string to change when a button click occurs in the react application. The specific object from which the value should be changed is already existing inside of the database, and only the value "In magazijn" should be changed to "Onderweg". This value should change inside of the database.
I have tried the following inside of the service class:
#Override
public String StatusOnderweg(Pakketje pakketje) {
return pakketjeRepository.save(pakketje.setStatus("Onderweg"));
}
So "Pakketje pakketje" is the object of which the string should be changed. I thought about saving the specific object once more to the database (even tough the object already exists) and save it with another string.
My Repository:
package com.Code.Pakket.management.repository;
import com.Code.Pakket.management.model.Pakketje;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
//https://www.javadevjournal.com/spring-boot/spring-boot-with-hibernate/ -- Punt5.
#Repository
public interface PakketjeRepository extends JpaRepository<Pakketje,Integer> {
}
I just don't have an idea how to make this code with a repository, service and controller structure... Any advice?
Thanks in advance.
Update: Link to repo is moved to answer because repo is now updated with code from answer below.
Problem description
Current code is working, but it is using gcloud beta emulators pubsub from google/cloud-sdk for integration tests.
Integration tests are slow due to the size of the google/cloud-sdk image
pubsub emulator has to run on a fixed port, there seems to be no way to tell Micronaut which port the emulator is running on
I'll need to set the following environment variable in maven-surefire-plugin.
<environmentVariables>
<PUBSUB_EMULATOR_HOST>localhost:8085</PUBSUB_EMULATOR_HOST>
</environmentVariables>
How this can be done in Spring Boot
According to Test Containers | Gcloud Module, the correct way of implementing integration tests with PubSubEmulatorContainer in Spring Boot is like this:
https://github.com/saturnism/testcontainers-gcloud-examples/blob/main/springboot/pubsub-example/src/test/java/com/example/springboot/pubsub/PubSubIntegrationTests.java
This will bring up the container on a random port, and that is possible because of DynamicPropertyRegistry in Spring. It seems that Micronaut is missing this possibility.
Doc: https://www.testcontainers.org/modules/gcloud/
I'm looking for a working example of a JUnit5 or Spock integration test implemented in Micronaut 3.x that is using PubSubEmulatorContainer like described in the above doc.
Related doc: https://micronaut-projects.github.io/micronaut-gcp/latest/guide/#emulator
There are some comments on GitHub around configuring TransportChannelProvider. I'm able to inject an instance and inspect it, but I still haven't found out exactly what to do.
These are the closest leads so far:
https://github.com/micronaut-projects/micronaut-gcp/issues/257
https://github.com/micronaut-projects/micronaut-gcp/pull/259
TL;DR
We'll need to start the testcontainer first, get emulator host address and then call ApplicationContext.run like this:
applicationContext = ApplicationContext.run(
["pubsub.emulator.host": emulatorHost])
Small Github repo with example code: https://github.com/roar-skinderviken/pubsub-emulator-demo
Long answer with code
I finally managed to make a working solution using Micronaut 3.0.2 and Spock. A related Micronaut PR got me on track, together with this article: Micronaut Testing Best Practices https://objectcomputing.com/files/9815/9259/7089/slide_deck_Micronaut_Testing_Best_Practices_webinar.pdf
First a PubSubEmulator class (Groovy)
package no.myproject.testframework.testcontainers
import org.testcontainers.containers.PubSubEmulatorContainer
import org.testcontainers.utility.DockerImageName
class PubSubEmulator {
static PubSubEmulatorContainer pubSubEmulatorContainer
static init() {
if (pubSubEmulatorContainer == null) {
pubSubEmulatorContainer = new PubSubEmulatorContainer(
DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk:emulators"))
pubSubEmulatorContainer.start()
}
}
}
Then a fixture for PubSubEmulator (Groovy)
package no.myproject.testframework.testcontainers
trait PubSubEmulatorFixture {
Map<String, Object> getPubSubConfiguration() {
if (PubSubEmulator.pubSubEmulatorContainer == null || !PubSubEmulator.pubSubEmulatorContainer.isRunning()) {
PubSubEmulator.init()
}
[
"pubsub.emulator-host": PubSubEmulator.pubSubEmulatorContainer.getEmulatorEndpoint()
]
}
}
Then a specification class (Groovy) that starts the container, creates a topic and a subscription.
The clue here is to pass in pubsub.emulator.host as part of the configuration when calling ApplicationContext.run.
Remaining part of the code is very similar to the Spring Boot example I linked to in my question.
package no.myproject.testframework
import com.google.api.gax.core.NoCredentialsProvider
import com.google.api.gax.grpc.GrpcTransportChannel
import com.google.api.gax.rpc.FixedTransportChannelProvider
import com.google.cloud.pubsub.v1.SubscriptionAdminClient
import com.google.cloud.pubsub.v1.SubscriptionAdminSettings
import com.google.cloud.pubsub.v1.TopicAdminClient
import com.google.cloud.pubsub.v1.TopicAdminSettings
import com.google.pubsub.v1.ProjectSubscriptionName
import com.google.pubsub.v1.PushConfig
import com.google.pubsub.v1.TopicName
import io.grpc.ManagedChannelBuilder
import io.micronaut.context.ApplicationContext
import no.myproject.configuration.GcpConfigProperties
import no.myproject.configuration.PubSubConfigProperties
import no.myproject.testframework.testcontainers.PubSubEmulatorFixture
import spock.lang.AutoCleanup
import spock.lang.Shared
import spock.lang.Specification
abstract class PubSubSpecification extends Specification
implements PubSubEmulatorFixture, EnvironmentFixture {
#AutoCleanup
#Shared
EmbeddedServer embeddedServer
#AutoCleanup
#Shared
ApplicationContext applicationContext
def setupSpec() {
// start the pubsub emulator
def emulatorHost = getPubSubConfiguration().get("pubsub.emulator-host")
// start a temporary applicationContext in order to read config
// keep any pubsub subscriptions out of context at this stage
applicationContext = ApplicationContext.run()
def gcpConfigProperties = applicationContext.getBean(GcpConfigProperties)
def pubSubConfigProperties = applicationContext.getBean(PubSubConfigProperties)
def channel = ManagedChannelBuilder.forTarget("dns:///" + emulatorHost)
.usePlaintext()
.build()
def channelProvider =
FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel))
// START creating topic
def topicAdminClient =
TopicAdminClient.create(
TopicAdminSettings.newBuilder()
.setCredentialsProvider(NoCredentialsProvider.create())
.setTransportChannelProvider(channelProvider)
.build())
def topic = TopicName.of(
gcpConfigProperties.getProjectId(),
pubSubConfigProperties.getTopicName())
try {
topicAdminClient.createTopic(topic)
} catch (AlreadyExistsException) {
// this is fine, already created
topicAdminClient.getTopic(topic)
}
// START creating subscription
pubSubConfigProperties.getSubscriptionNames().forEach(it -> {
def subscription =
ProjectSubscriptionName.of(gcpConfigProperties.getProjectId(), it)
def subscriptionAdminClient =
SubscriptionAdminClient.create(
SubscriptionAdminSettings.newBuilder()
.setTransportChannelProvider(channelProvider)
.setCredentialsProvider(NoCredentialsProvider.create())
.build())
try {
subscriptionAdminClient
.createSubscription(
subscription,
topic,
PushConfig.getDefaultInstance(),
100)
System.out.println("Subscription created " + subscriptionAdminClient.getSubscription(subscription))
} catch (AlreadyExistsException) {
// this is fine, already created
subscriptionAdminClient.getSubscription(subscription)
}
})
channel.shutdown()
// stop the temporary applicationContext
applicationContext.stop()
// start the actual applicationContext
embeddedServer = ApplicationContext.run(
EmbeddedServer,
[
'spec.name' : "PubSubEmulatorSpec",
"pubsub.emulator.host": emulatorHost
],
environments)
applicationContext = embeddedServer.applicationContext
}
}
Then a factory class (Groovy) for mocking credentials
package no.myproject.pubsub
import com.google.auth.oauth2.AccessToken
import com.google.auth.oauth2.GoogleCredentials
import io.micronaut.context.annotation.Factory
import io.micronaut.context.annotation.Replaces
import io.micronaut.context.annotation.Requires
import javax.inject.Singleton
#Factory
#Requires(property = 'spec.name', value = 'PubSubEmulatorSpec')
class EmptyCredentialsFactory {
#Singleton
#Replaces(GoogleCredentials)
GoogleCredentials mockCredentials() {
return GoogleCredentials.create(new AccessToken("", new Date()))
}
}
And finally, a Spock test spec.
package no.myproject.pubsub
import no.myproject.testframework.PubSubSpecification
import java.util.stream.IntStream
class PubSubIntegrationSpec extends PubSubSpecification {
def NUMBER_OF_MESSAGES_IN_TEST = 5
def DELAY_IN_MILLISECONDS_PER_MSG = 100
def "when a number of messages is sent, same amount of messages is received"() {
given:
def documentPublisher = applicationContext.getBean(DocumentPublisher)
def listener = applicationContext.getBean(IncomingDocListenerWithAck)
def initialReceiveCount = listener.getReceiveCount()
when:
IntStream.rangeClosed(1, NUMBER_OF_MESSAGES_IN_TEST)
.forEach(it -> documentPublisher.send("Hello World!"))
// wait a bit in order to let all messages propagate through the queue
Thread.sleep(NUMBER_OF_MESSAGES_IN_TEST * DELAY_IN_MILLISECONDS_PER_MSG)
then:
NUMBER_OF_MESSAGES_IN_TEST == listener.getReceiveCount() - initialReceiveCount
}
}
The chosen answer is a good deal more complicated than necessary, and it also contains numerous typos. A better answer can be found via the Micronaut GCP codebase itself, with the key bit being:
class IntegrationTestSpec extends Specification {
static CONTAINER_PORT = -1
static CredentialsProvider CREDENTIALS_PROVIDER
static TransportChannelProvider TRANSPORT_CHANNEL_PROVIDER
static PubSubResourceAdmin pubSubResourceAdmin
static GenericContainer pubSubContainer = new GenericContainer("google/cloud-sdk:292.0.0")
.withCommand("gcloud", "beta", "emulators", "pubsub", "start", "--project=test-project",
"--host-port=0.0.0.0:8085")
.withExposedPorts(8085)
.waitingFor(new LogMessageWaitStrategy().withRegEx("(?s).*Server started, listening on.*"))
static {
pubSubContainer.start()
CONTAINER_PORT = pubSubContainer.getMappedPort(8085)
CREDENTIALS_PROVIDER = NoCredentialsProvider.create()
def host = "localhost:" + IntegrationTest.CONTAINER_PORT
ManagedChannel channel = ManagedChannelBuilder.forTarget(host).usePlaintext().build()
TRANSPORT_CHANNEL_PROVIDER =
FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel))
pubSubResourceAdmin = new PubSubResourceAdmin(TRANSPORT_CHANNEL_PROVIDER, CREDENTIALS_PROVIDER)
}
}
You'd then just extend that class anywhere you wanted to make use of PubSub. The following is slightly cleaner example that I came up with which manages creating a topic as well during test startup:
#Slf4j
abstract class PubSubSpec extends Specification implements TestPropertyProvider {
static final String cloudSdkName = System.getenv('CLOUD_SDK_IMAGE') ?: "gcr.io/google.com/cloudsdktool/cloud-sdk:emulators"
static final DockerImageName cloudSdkImage = DockerImageName.parse(cloudSdkName)
static final PubSubEmulatorContainer pubsubEmulator = new PubSubEmulatorContainer(cloudSdkImage)
static {
pubsubEmulator.start()
ManagedChannel channel = ManagedChannelBuilder.forTarget(pubsubEmulator.getEmulatorEndpoint()).usePlaintext().build()
try {
TransportChannelProvider channelProvider = FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel))
CredentialsProvider credentialsProvider = NoCredentialsProvider.create()
TopicAdminClient topicClient = TopicAdminClient.create(
TopicAdminSettings.newBuilder()
.setTransportChannelProvider(channelProvider)
.setCredentialsProvider(credentialsProvider)
.build()
)
TopicName topicName = TopicName.of("project-id", "project-topic")
topicClient.createTopic(topicName)
} finally {
channel.shutdown()
}
}
#Override
Map<String, String> getProperties() {
[
"pubsub.emulator.host": pubsubEmulator.getEmulatorEndpoint()
]
}
}
I get "Error while updating 'end' in shadow node of type: BVLinearGradient" error when i run my react native app and the error seems to emanate from my MainApplication.java file here is my code:
package com.*;
import com.BV.LinearGradient.LinearGradientPackage;
import com.facebook.react.ReactPackage;
import com.horcrux.svg.SvgPackage;
import com.oblador.vectoricons.VectorIconsPackage;
import com.reactnativenavigation.NavigationApplication;
import com.wheelpicker.WheelPickerPackage;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends NavigationApplication {
#Override
public boolean isDebug() {
// Make sure you are using BuildConfig from your own application
return BuildConfig.DEBUG;
}
#Override
public List<ReactPackage> createAdditionalReactPackages() {
// Add the packages you require here.
// No need to add RnnPackage and MainReactPackage
return Arrays.<ReactPackage>asList(
new WheelPickerPackage(),
new VectorIconsPackage(),
new SvgPackage(),
new LinearGradientPackage()
);
}
}
Please help me resolve this
This is a bug with the react-native-linear-gradient. The issue is in open status. For the time being, there are 2 solutions-
Replace start with startPoint and end with endPoint props for <LinearGradient/>
Downgrade react-native version to 0.50.3
The details for this issue is below:
https://github.com/react-native-community/react-native-linear-gradient/issues/246
Getting error as "There are undefined steps" while running the cucumber test with testNG in intelliJ editor, please guide with the steps that are missing
the error output as
Feature: New Tour Login Testing
Scenario: Valid data testing # src/main/java/features/loginnewtour.feature:2
Given user is already on Login Page
When title of login page is new tour
Then user enters "mercury"
cucumber.runtime.CucumberException: cucumber.runtime.CucumberException: There are undefined steps
at cucumber.api.testng.TestNGCucumberRunner.runCucumber(TestNGCucumberRunner.java:69)
at cucumber.api.testng.AbstractTestNGCucumberTests.feature(AbstractTestNGCucumberTests.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:643)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:820)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1128)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
at org.testng.TestRunner.privateRun(TestRunner.java:782)
at org.testng.TestRunner.run(TestRunner.java:632)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
at org.testng.SuiteRunner.run(SuiteRunner.java:268)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
at org.testng.TestNG.run(TestNG.java:1064)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Caused by: cucumber.runtime.CucumberException: There are undefined steps
at cucumber.api.testng.FeatureResultListener.collectError(FeatureResultListener.java:60)
at cucumber.api.testng.FeatureResultListener.result(FeatureResultListener.java:45)
at cucumber.runtime.Runtime.runStep(Runtime.java:282)
at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:44)
at cucumber.runtime.model.CucumberFeature.run(CucumberFeature.java:165)
at cucumber.api.testng.TestNGCucumberRunner.runCucumber(TestNGCucumberRunner.java:63)
... 24 more
Undefined scenarios:
src/main/java/features/loginnewtour.feature:2 # Scenario: Valid data testing
1 Scenarios (1 undefined)
3 Steps (3 undefined)
0m0.000s
Below are the files that I am using under
src/main/java/
features
loginnewtour.feature
myRunner
TestRunner.java
stepDef
loginstepdefnewtour.java
I have a feature file as "loginnewtour.feature"
Feature: New Tour Login Testing
Scenario: Valid data testing
Given user is already on Login Page
When title of login page is new tour
Then user enters "mercury"
implemented all steps mentioned in the feature file as "loginstepdefnewtour.java"
package stepDef;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import org.openqa.selenium.chrome.ChromeDriver;
public class loginstepdefnewtour {
WebDriver driver;
#Given("^user is already on Login Page$")
public void user_is_already_on_Login_Page() throws Throwable {
System.setProperty("webdriver.chrome.driver","c:\\Grid\\chromedriver.exe");
driver = new ChromeDriver();
driver.get("http://newtours.demoaut.com/");
}
#When("^title of login page is new tour$")
public void title_of_login_page_is_new_tour() throws Throwable {
String title = driver.getTitle();
System.out.println(title);
}
#Then("^user enters \"([^\"]*)\"$")
public void user_enters_and(String arg1, String arg2) throws Throwable {
driver.findElement(By.name("userName")).sendKeys("sunil");
}
}
and "testrunner.java" is as
package myRunner;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;
//#RunWith(Cucumber.class)
#CucumberOptions(
features = "src/main/java/features/loginnewtour.feature",
glue={"src/main/java/stepDef/loginstepdefnewtour.java"},
plugin= {"pretty","html:test-outout", "json:json_output/cucumber.json", "junit:junit_xml/cucumber.xml"},
monochrome = true,
strict = true,
dryRun = false
)
public class TestRunner extends AbstractTestNGCucumberTests{
}
You specified a wrong value for the glue path. You need to specified the Java packages to search for.
instead of
glue={"src/main/java/stepDef/loginstepdefnewtour.java"},
it should be
glue={"stepDef"},
Also a method signature is wrong
-- public void user_enters_and(String arg1, String arg2) throws Throwable {
public void user_enters_and(String arg1) throws Throwable {
edit The files in the project with the naming you provided (please consider to follow the Java naming convention for the files)
src/main/java/stepDef/loginstepdefnewtour.java
src/main/java/features/loginnewtour.feature
src/test/java/myRunner/TestRunner.java
loginstepdefnewtour.java
package stepDef;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class loginstepdefnewtour {
#Given("^user is already on Login Page$")
public void user_is_already_on_Login_Page() throws Throwable { }
#When("^title of login page is new tour$")
public void title_of_login_page_is_new_tour() throws Throwable { }
#Then("^user enters \"([^\"]*)\"$")
public void user_enters_and(String arg1) throws Throwable { }
}
loginnewtour.feature
Has the content you provided.
TestRunner.java
package myRunner;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;
//#RunWith(Cucumber.class)
#CucumberOptions(
features = "src/main/java/features/loginnewtour.feature",
glue={"stepDef"},
plugin= {
"pretty","html:test-outout",
"json:json_output/cucumber.json",
"junit:junit_xml/cucumber.xml"
},
monochrome = true,
strict = true,
dryRun = false
)
public class TestRunner extends AbstractTestNGCucumberTests{
}
Execute the tests
mvn compile test
output
Running myRunner.TestRunner
Configuring TestNG with: org.apache.maven.surefire.testng.conf.TestNG652Configurator#6bf2d08e
Feature: New Tour Login Testing
Scenario: Valid data testing # src/main/java/features/loginnewtour.feature:2
Given user is already on Login Page # loginstepdefnewtour.user_is_already_on_Login_Page()
When title of login page is new tour # loginstepdefnewtour.title_of_login_page_is_new_tour()
Then user enters "mercury" # loginstepdefnewtour.user_enters_and(String)
1 Scenarios (1 passed)
3 Steps (3 passed)
I would like to externalise my selenium tests setting in order to make them more configurable.
I would like to externalise my testURL and my node URLS.
Here is my code :
public void setup () throws MalformedURLException
{ //the URL of the application to be tested
TestURL = "http://frstmwarwebsrv2.orsyptst.com:9000";
//Hub URL
BaseURL = "http://10.2.128.126";
//Node1 URL
winURL = "http://10.2.128.120:5556/wd/hub";
//Node2 URL
androidURL ="http://10.2.128.120:5555/wd/hub";
At the moment I have added this setup function in every test I would like to have it in an XML file for an example in order to make it configurable, any suggestions?
Thanks
Thanks for your help
Update :
Here is what i did so far :
Added a config.properties file with this content :
# This is my test.properties file
AppURL = http://************
HubURL= http://*****************
WinURL= http://*********/wd/hub
AndroidURL =
iOSURL
And created a classe to read properties :
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
public class ReadPropertiesFile {
public static void main(String[] args) {
try {
File file = new File("config.properties");
FileInputStream fileInput = new FileInputStream(file);
Properties properties = new Properties();
properties.load(fileInput);
fileInput.close();
Enumeration enuKeys = properties.keys();
while (enuKeys.hasMoreElements()) {
String key = (String) enuKeys.nextElement();
String value = properties.getProperty(key);
System.out.println(key + ": " + value);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
when running this i get this error :
java.io.FileNotFoundException: config.properties (The system cannot find the file specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(Unknown Source)
at ReadPropertiesFile.main(ReadPropertiesFile.java:15)
my properties file is under src folder
Two basic ways you could do this are:
Pass in JVM argument and access it using System.getProperty(...)
Externalize your configuration in to properties files, like here
I recently implemented the second one in my Selenium tests and can expand this answer to give more details if you need them.
In my tests, I resolved it that I created Java class called Environment to store information about given Environment:
Few snippets of code:
public enum NameOfEnvironment {
SYSTEMTEST, ACCEPTANCE
}
stores the Name of given Environment :)
public String getBaseUrl() {
switch (actualEnvironment) {
case SYSTEMTEST: {
baseUrl = getPrefix() + "172.23.32.251:9092/pages/index.html";
break;
}
will return me the URL to the environment. And on beginning of the test I have something like this:
public static final Environment USED_ENVIRONMENT = new Environment(Environment.NameOfEnvironment.SYSTEMTEST);
And later on I just call USED_ENVIRONMENT.getBaseUrl() which will return me the link which is being actual for current run
Btw, to fill in the blanks, here is the constructor f the class
public Environment(NameOfEnvironment env) {
this.actualEnvironment = env;
}