Multi Threading in web application - java

I have class which is used to display the current location in the bread crumb.
This class is getting initialised per user from the front end.
my question is do I need to synchronise the methods in this class if yes which are methods needs to be synchronised .There is some confusion. so please advise.
public class CrumbNav {
private Stack<Crumb> stack;
private Crumb crumb;
public CrumbNav() {
stack = new Stack<Crumb>();
crumb = new Crumb("Home");
stack.push(crumb);
}
public void addcrumb(String current) {
Crumb newCrumb = new Crumb(current);
if (stack.peek().equals(newCrumb)) {
return;
}
stack.push(newCrumb);
}
public void removeCurrent() {
stack.pop();
}
public void eraseTrail() {
stack.clear();
stack.push(crumb);
}
public void removeCrumbsClicked(Crumb selected) {
while (true) {
if (stack.peek().equals(selected) || stack.isEmpty())
break;
stack.pop();
}
}
public Crumb getLastBreadCrumb() {
return stack.lastElement();
}
public Crumb getPreviousCrumb() {
if (stack.size() > 1) {
return stack.get(stack.size() - 2);
}
return null;
}
public List<Crumb> getCrumbTrail() {
return stack.subList(0, stack.size());
}
}

It depends on what web framework you're using as to if the object is created per-thread, or as a singleton for the entire session. Spring will, by default, create a single instance and may require synchronization. Other web frameworks may not.
Note that in the "happy path" world, there's only one active thread rendering a page for any given user, but there's nothing stopping the user from rapid-fire clicking on different link initiating many connections and therefore threads.

(I mentioned this in comments, I think it's better to make it an answer.)
There are so many web framework in the industry, who knows how they gonna use your class? The best way is to test whether multiple thread gonna access the same instance concurrently.
Maintain a concurrent set in your class. Every time the method been called, add currentThread.thread_id into the set. Then output the set at last, seeing that whether it's been called from multiple threads. If so, then rewrite your class to a thread-safe version.

Tracking navigation is normally on a per user basis. This class contains storage of the navigation state - which is user specific state, so you need one instance per user session. The methods don't need to be synchronised unless there is the possibility of the same user re-entrantly entering the web server (as mentioned by PaulProgrammer).
Some frameworks will allow this. It can be prevented in Spring MVC by setting the synchronizeOnSession controller property, and there are likely similar techniques for other frameworks.

Related

Selenium Java: With TestNG, Not executing 2nd test case

Console Output
Please help me to fix the below issue in Selenium WebDriver with Java.
I am validating eComm web based application. I have couple of test cases.
1. Sign in to the application
2. Add to item to the cart. This test case is a continuation of first test case. It means that after sign in, user is gonna add the item to the cart.
I have 2 class files, In that I have given #Test condition in both the class files.
In CommonFunctions class file, I am lauching browser in #BeforeSuite section. And closing the browser in #AfterSuite section.
I am doing it in Page object model and executing from TestNG XML.
On running the suite, First test case is getting passed. When it comes to the second test case (In the #Test condition present in the 2nd class file), the in it entering into the #Test section but getting failed immediately with out any reason.
I have tried with Implicit, Explicit wait and even thread.sleep as well. But no luck. Please can some one take a look and suggect me.
Appreciate your help!
I assume that it is getting failed for some exception and the stack trace is not getting printed somehow. Try explicitly getting it printed by:
#Test
public void SecondTestCase(){
try{
yourSecondTestCase;
}
catch(Throwable e){
e.printStackTrace();
}
}
Just don't reuse the driver.
Create it in #BeforeMethod then quit it in #AfterMethod and you should not meet any issues.
Update answering a comment question below:
In general it's not a good idea to have the tests depending on each other.
Regardless of how special you think your case is, you should never do it if you want to keep your dignity.
This does not neccessarily mean that you can't reuse 'logic' in tests, it just means that you should not expect any other test to have executed before the current one.
Let's put some thought about it:
Why would you want to do it at first place?
What is the effect that you're seeking?
My blind-guess answers are:
You want to have the login test executed first.
This will help you avoid repeating the same login code in all of the remaining tests, and you save time from starting/stopping the driver.
If my guesses are correct, then I can tell you that it's perfectly normal to want those things, and that everyone who ever needed to write more than 2 tests has been there
You may ask:
Am I not trying to achieve the same thing?
Where is my mistake then?
The following answers can be considered brief and quite insufficient compared to the truth that lies beneath, but I think they will serve you as a good starting point for where you're heading at.
Yes, you're trying to achieve the same thing.
Your approach can't be called mistake, but negliance - you're trying to write automated tests with Selenium while you lack basic coding skills. It's actualy not so bad, because you didn't knew what you're getting into, but after reading this you have the choice of either letting it slip or begin the journey to personal improvement. Take some time to learn Java - a really good starter would be the 'Thinking in Java' book. Do make the exercises after each chapter and the experience that you'll gain will be priceless. The book will help you get familiar with the Java language features and good idea of how code organization works.
Enough with the general notes, below is a simple guide for you to follow in implementing v0.1 of your newly-born 'automation project'.
(Yes, it is 'project' and 'framework' is having completely different meaning, to be clear.)
First you need to decide how to approach the page objects.
(Based on my own experience)
the best way to do it is to keep all the business-logic inside the page objects and by business-logic I mean:
all the methods that perform some action,
and all the methods that retrieve some data.
Examples include doSomething / getSometing / setSomething / isSomething / canSomething / waitSomething and so on.
You should not be doing any assertions inside the page objects
You should never throw AssertionError from your page objects
If you need to throw something from page-object method/constructor just
throw IllegalArgumentException
or RuntimeException.
All the assertions should happen exclusively in the test-method-body
You should never write 'assert...' statement outside #Test method
You can have Util classes to do some data transformations
but do not ever write assertion logic inside them
rather expose methods with boolean/other return type and assert on their result.
The following example is one of the best I've ever seen:
// Don't do this:
ColorVerifications.assertAreSame(pen.getColor(), ink.getColor());
// If you do, you'll eventually end-up having to write this:
ColorVerifications.assertAreNotSame(pen.getColor(), ink.getColor());
// Do this instead:
Assert.isTrue(ColorUtil.areSame(pen.getColor(), ink.getColor());
// Then you can actually 'reuse' the logic that's already in the Assert class:
Assert.isFalse(ColorUtil.areSame(pen.getColor(), ink.getColor());
// NOTE: Regarding the term "code reuse"
// - it is NOT referring to "reusing your own code"
// - it IS referring to "reusing all the existing code"
The idea is to clearly communicate both the assert intention and how the check is done.
Always keep the logic of 'checking' and 'asserting' separate, becuse those words are having different semantics.
It is really important to put a good amount of thinking when naming classes / methods / variables - really!
Don't be afraid to rename it when you come up with a better fit - go for it on the spot!
Now back to our page obects and login stuff - I won't be diving much into it but, you'll get where I'm going at.
Carefully organize the #Test methods in separate classes
Keep the ones that need common setup in the same class
Keep the number of test-class methods that are not annotated with #Test to the minimum
Do not inherit between test classes to reuse logic other than
Outputs/Results folders preparaton/colletion/archiving
Logs/Reports initialization/disposal
Driver creation/cleanup
In general: prefer composition to inheritance
Put other logic in the page objects / util classes and reuse them
Have a base DriverWrapper class for the generic UI checks/interactions
Have a base PageObject class that is hosting a DriverWrapper member
Don't use the #FindBy / PageFactory model (you'r life will be happier)
Use static final By locators instead
Log everything!
logging is not included in the examples
but do assume every method's first line is logging the method name and the passed arguments
always remember - your log is your best friend
Reading what happened in the log takes considerably less time than manually debugging the code (which is pratically re-running it at half-speed)
You are writing atuomation code, not production code so you can nevver be wrong when logging additional info.
Except for the cases of passwords and confidential data
those you should never log.
Now that you have been thaught some basic ideas, lets dive into code:
Page basics
Sample DriverWrapper:
class DriverWrapper {
protected final WebDriver driver;
public DriverWrapper(WebDriver driver){
this.driver = Objects.requireNotNull(driver, "WebDriver was <null>!");
}
// it's okay to have 'checked exceptions' declared by all wait* methods
// but it is tottaly not okay to have 'checked exceptions' for the others
public WebElement waitForVisibleElement(By locator, int timeoutMillis)
throws TimeoutException { // <- the 'checked exception'
return new WebDriverWait(driver)
.withTimeout(Duration.ofMillis(timeoutMillis))
.pollingEvery(Duration.ofMillis(100))
.until(
ExpectedConditions.visibilityOfElementLocatedBy(locator)
);
}
public boolean isVisible(By locator, int timeoutMillis){
try{
return waitForVisibleElement(locator, timeoutMillis) != null;
catch(TimeoutException ignored){
return false;
}
}
// .get(String url){...}
// .click(By locator){... elementToBeClickable(locator) ....}
// .typeInto(bool shouldLog, By locator, CharSequence... keys){...}
// .typeInto(By locator, CharSequence... keys){typeInto(true, locator, keys);}
// you got the idea ;)
}
Sample PageObject:
class PageObject{
protected final DriverWrapper driver;
public PageObject(WebDriver driver){
this.driver = new DriverWrappr(driver);
}
}
Sample LoginPage:
class LoginPage extends PageObjet{
// NOTE: keep the locators private
private static final By USERNAME_INPUT = By.id("usernameInput");
private static final By PASSWORD_INPUT = By.id("passwordInput");
private static final By LOGIN_BUTTON = By.id("loginButton");
private static final By ERROR_MESSAGE = By.id("errorMessage");
public LoginPage(WebDriver driver){
super(driver);
}
public LoginPage goTo(){
driver.get(url);
return this;
}
public void loginAs(String user, String pass){
// NOTE:
// Do not perform navigation (or other actions) under the hood!
// Resist the urge to call goTo() here!
// Page object methods should be transparent about what they do.
// This results in better level of control/transparency in the tests.
driver.typeInto(USERNAME_INPUT, user);
driver.typeInto(PASSWORD_INPUT, pass);
driver.click(LOGIN_BUTTON);
}
public boolean isErrorMessageVisible(int timeoutMillis){
// NOTE: We delegate the call to the driver
// Allowing the page-object to later define it's own isVisible method
// Without having collision with driver methods.
return driver.isVisible(ERROR_MESSAGE, timeoutMillis);
}
}
Infrastructure basics
Sample DriverManager class:
class DriverManager{
private static WebDriver driver;
public static WebDriver getDriver(){
return driver;
}
public static void setDriver(WebDriver driver){
// NOTE: Don't do null checks here.
DriverManager.driver = driver;
}
public static WebDriver createDriver(String name){
//...
return new ChromeDriver();
}
Sample TestBase class:
class TestBase{
// NOTE: just define the methods, do not annotate them.
public static void setUpDriver(){
// In v0.1 we'll be sharing the driver between tests in same class
// Assuming the tests will not be running in parallel.
// For v1.0 you can improve the model after reading about test-listeners
WebDriver driver = DriverManager.getDriver();
if(driver != null){
return;
}
driver = DriverManager.createDriver("chrome");
DriverManager.setDriver(driver);
}
public static void tearDownDriver(){
WebDriver driver = DriverManager.getDriver();
if(driver != null){
driver.quit();
DriverManager.setDriver(null);
}
}
}
Finally - a test class:
class LoginTests extends TestBase{
private LoginPage loginPage;
#BeforeClass
public static void setUpClass(){
setUpDriver();
}
#AfterClass
public static void tearDownClass(){
tearDownDriver();
}
#BeforeMethod
public void setUp(){
// actions, that are common for all test cases in the class
loginPage = new LoginPage(DriverManager.getDriver());
loginPage.goTo();
}
#AfterMethod
public void tearDown(){
// dispose the page objets to ensure no local data leftovers
loginPage = null;
}
#Test
public void testGivenExistingCredentialsWhenLoginThenNoError(){
loginPage.loginAs("TestUser", "plain-text password goes here");
boolean errorHere = loginPage.isErrorMessageVisible(30 * 1000);
Assert.assertFalse(errorHere, "Unexpected error during login!");
}
#Test
public void testGivenBadCredentialsWhenLoginThenErrorShown(){
loginPage.loginAs("bad", "guy");
boolean errorHere = loginPage.isErrorMessageVisible(30 * 1000);
Assert.assertTrue(errorHere, "Error message not shown!");
}
}
That's all there is to it.
Hope you enjoyed the ride.

Concept to create thread wide/class wide object

I'm searching for a concept to forward an object to subobjects.
Example:
I would like to create log files for several main Objects, that include sub objects (imagine a REST server that would log every single connection by ID).
Creating one big log file is simple ( redirect System.out.println, I already encapsulated that)
Example code:
class SubElementA{
public SubElementA(){
Debugger.debug("I am called, too");
}
}
Application.java
package com.dev4ag;
class Application{
private ElementA elA;
private String prefix;
public Application(String name){
this.elA = new ElementA();
this.prefix = name;
}
public void countUp(){
Debugger.debug(this.prefix+": I will now count up");
this.elA.doSomeStuff();
}
}
ElementA.java
package com.dev4ag;
class ElementA{
private int counter;
private SubElementA subElementA;
public void doSomeStuff(){
counter++;
Debugger.debug("Counter is: "+counter);
}
//Constructor
public ElementA(){
subElementA = new SubElementA();
this.counter = 0;
};
}
SubElementA.java
package com.dev4ag;
class SubElementA{
public SubElementA(){
Debugger.debug("I am called, too");
}
}
Debugger.java
package com.dev4ag;
public class Debugger {
public static void debug(String output){
//Just imagine we would write to a file here ;)
System.out.println(output);
}
}
(it was more easy to write system.out.println than to create a file, just imagine, Debugger.debug would write to a file).
Now I am thinking about a solution to create one Debug output target for each App. I could definitely change debug to not being static and create a debug object within Application.
But is there any way to use this object in the sub classes without forwarding the debug object either through Constructor or setter function, which would mean to have to add an object for the debugger to each class?
What would be the most beautiful solution for that?
Note that this solution might decrease performance a lot and it is pretty dirty way, but some loggers include such data.
But you can use Thread.currentThread().getStackTrace() to get stacktrace like in error and get class and method from where your method was called.
If you are using java9+ then you should probably use StackWalker API instead, especially that it have nice filters and other useful features.
So then you could guess app by class/method names on the stack.

Design for CLI system that will have a GUI later

Working on a platform that currently has a CLI, but later will have a GUI.
Java.
Basically, currently has a Platform class that orchestrates the interaction of pluggable elements. Platform is a singleton.
There is a CLI class, which has Commands that can use the Platform and its plugins.
Sometimes the Commands employ Platform components (plugins) that require further user interaction (input and output). I am thinking of making a UI interface that Platform is configured with, and the components then make calls out to this to display and obtain input. An event driven solution.
Is that a valid design?
Is there something better?
I am trying to make an MVC style approach work in my head, but the problem is it seems to imply a lot of fore-knowledge in the CLI Commands (ie, the controllers), about the Platform components. That makes them tightly coupled, and I'd like to keep the commands as general as possible. That makes them easier for extenders to work on them, and makes fewer of them for the coming GUI development.
MVC pattern is useful to build the UI (be it CLI, GUI, web page, REST API or something totally different). For integration purposes, you'll want to use other patterns, for instance Facade.
Let's say you're building an ice cream machine. You have a platform interface:
package com.plaform.icecream;
public interface IceCreamMachine {
public void measureCream(int milliLiters);
public void measureCondensedMilk(int milliLiters);
public void measureVanillaExtract(int tableSpoons);
public void measureCacaoPowder(int tableSpoons);
public void mixIngredients();
public void freezeConcoction();
public Object handOverExperimentResults();
}
Then you have your model class of MVC:
package com.cli.icecream.model;
public class Icecream {
private int amount;
private Flavour flavour;
// getters, setters, toString, etc.
}
Flavours as enum:
package com.cli.icecream.model.values;
public enum Flavour {
VANILLA, CHOCOLATE;
}
Controller:
package com.cli.icecream.controller;
public class IceCreamController {
private IceCreamFacade serviceFacade;
public IceCreamController(IceCreamFacade serviceFacade) {
this.serviceFacade = serviceFacade;
}
public void handleShowingFlavours() {
// ...
}
public IceCream handleOrderingIcecream(int balls, Flavour flavour) {
// validations, etc.
return serviceFacade.getIceCream(balls, flavour);
}
}
Now the way to hide the actual details behind the product from the MVC, you can create a Facade that will integrate the two:
package com.cli.icecream.integration;
public interface IceCreamFacade {
public IceCream getIceCream(int balls, Flavour flavour);
}
and:
package com.cli.icecream.integration;
public class IceCreamFacadeImpl {
private IceCreamMachine iceCreamMachine;
public IceCreaFacadeImpl(IceCreamMachine iceCreamMachine) {
this.iceCreamMachine = iceCreamMachine;
}
public IceCream getIceCream(int balls, Flavour flavour) {
int creamMl = ConversionUtil.calculateAmountOfCream(balls);
int condensedMilkMl = ConversionUtil.calculateAmountOfCondensedMilk(balls);
int flavourSubstanceTbsp = ConversionUtil.calculateAmountOfFlavourSubstance(balls);
iceCreamMachine.measureCream(creamMl);
iceCreamMachine.measureCondensedMilk(condensedMilkMl);
switch (flavour) {
case VANILLA:
iceCreamMachine.measureVanillaExtract(flavourSubstanceTbsp);
break;
case CHOCOLATE:
iceCreamMachine.measureCacaoPowder(flavourSubstanceTbsp);
break;
}
mixIngredients();
freezeConcoction();
Object results = iceCreamMachine.handOverExperimentResults();
return ConversionUtil.convertResultsToIceCream(results);
}
}
This way the UI (MVC) consist of classes that are blissfully unaware of how the integrated platform works and vice versa, i.e. decoupled. As an added benefit, if either component changes its behaviour, all your logic to integrate the two are in one place, instead of splattered all over either application.

Static variables, pattern and Android performance

I'm doing some big refactoring operations relative to some performance improvements in an android app which is using a class with lot of static variables and even static activity references which are then use through the app ! So I was looking for some best practices in Android to store data and give to these data a global access in my app.
First I removed all the activity references to avoid any memory leak, but I'm still looking to know what is the best practice regarding static variables which need to be used anywhere in the android app.
I read many times (example1, exemple2) : using static variables is not necessary a good practices and it's better/cleaner to use one singleton class with getter and setter to have access to my global variables whatever the activity where I am. So what I've started to think is a class which could looks like this one :
public class AppSingleton extends Application {
private static AppSingleton appInstance;
// different stored data, which could be relative to some settings ..
private String setting1;
private String setting2;
private AppSingleton() {
super();
appInstance = new AppSingleton();
}
public static AppSingleton getAppInstance() {
if (appInstance == null) {
appInstance = new AppSingleton();
}
return appInstance;
}
// Getter and Setter for global access
public String getSetting1() {return setting1;}
public void setSetting1(String setting1) {this.setting1 = setting1;}
public String getSetting2() {return setting2;}
public void setSetting2(String setting2) {this.setting2 = setting2;}
}
Then I can use for example :
// Get the application instance
AppSingleton appS = (App) getApplication();
// Call a custom application method
appS.customAppMethod();
// Call a custom method in my App singleton
AppSingleton.getInstance().customAppSingletonMethod();
// Read the value of a variable in my App singleton
String var = AppSingleton.getInstance().getCustomVariable;
For me AppSingleton sounds good because this singleton which restrics ths instantiation of this class to one object, also this class is not destroyed until there are any undestroyed Activity in the application so it means I can keep my global data in the current lifecycle of my app for example from a 'Log in'. But also I can maintain the state of my global variables from my getters/setters.
But then I also had a look on the official android documentation about Performance Tips which say it's good to use static variable it's faster and don't forget to avoid internal getter and setter it's too expansive !
I'm a bit confused about all of these and I'm really keen to learn more about that topic. What is the best practices about using one class to provide an access to some variables which are needed in different part of my code ? Is the class above AppSingeleton is something which could be interesting to use in terms of architecture and performance ?
Is it a good idea to use a singleton pattern for managing global variables in android ?
those lines are completely wrong on your code:
private AppSingleton() {
super();
appInstance = new AppSingleton();
}
public static AppSingleton getAppInstance() {
if (appInstance == null) {
appInstance = new AppSingleton();
}
return appInstance;
}
you cannot instantiate new Application, the Android framework instantiates it. Change to this:
private AppSingleton() {
super();
appInstance = this; // keep ref to this application instance
}
public static AppSingleton getAppInstance() {
return appInstance;
}
Regarding the accessing of global variables. I believe it's more organized to have those singletons somewhere else on your application. The application class have different responsibilities you should not overload it with different tasks. That's OO clean coding.
Also, sometimes there's not that much reason in an Android app to have getters/setters for everything, because u don't need as much access control as in bigger projects. But this should be considered case-by-case about the necessity and not be used a general rule.
So you could for example have it like:
public class Globals {
private static final Globals instance = new Globals();
public static Globals get() { return instance; }
public String value1 = "Hello"
public int value2 = 42;
}
then on your code call as needed:
Log.d(TAG, Globals.get().value1);
Globals.get().value1 = "World";
Log.d(TAG, Globals.get().value1);
Log.d(TAG, "Value2 = " + Globals.get().value2);

Good way to load ressources

I am developping a server application in Java. I need to load some ressources from different sources (XML and a Database). So, i need some advice on how to cleanly implement the loading.
I have a class "ServerX" who create some "Memory" object, it's those objets who'll hold the loaded ressources.
I've found two different way of loading, but both seems dirty.
1
public class ServerX
{
/**
Will hold the houses for further use.
*/
private Memory<House> houses;
public ServerX()
{
houses = new Memory<House>();
loadHouses();
loadXX();
loadYY();
LoadZZ();
Load...
}
private void loadHouses()
{
//Pseudo code
List<House> loaded = loadHousesFromDatabase();
houses.addAll(loaded);
}
private void loadXX();
...
}
But this way, it flood my "ServerX" class.
2
public interface Loader
{
public void loadHouses(Memory<House> toFill);
public void loadXX(Memort<XX> toFill);
public void loadYY(Memort<YY> toFill);
public void loadZZ(Memort<ZZ> toFill);
}
public class SimpleLoader implements Loader
{
//Implements methods.
}
public class ServerX
{
/**
Will hold the houses for further use.
*/
private Memory<House> houses;
public ServerX(Loader loader)
{
houses = new Memory<House>();
loader.loadHouses(houses);
loader.loadXX...
}
}
But this way, i think i fall into the Poltergeist antipattern, because i create a new loader only to do the request to the database/XML file, and then it's garbage-collected.
So, is there another way to do it, or is one of my solutions good enough?
Thanks.
One pattern you can consider is the Service Locator Pattern. An explanation of Service Locator can be found here.
Basically, a service locator is a registry + cache combined to find the resource once and keep it in memory for object retrieval during the lifecycle of the application. Service Locator is mainly implemented using the Singleton pattern.
Your second solution using a Loader interface and multiple implementations (XMLLoader and DBLoader) is good. However, keep the loader and the server decoupled by making the load methods return a new Memory instance instead of passing the memory as a reference. Add a copyAll method in Memory class to copy the contents of one memory into another memory. ( See ArrayList.addAll or System.arrayCopy in javadoc )

Categories