Thursday 28 February 2013

Downloading the Source Code from App Engine




Download Google App Engine SDK from https://developers.google.com/appengine/downloads, install it.
Follow the steps to download source code:
  • Step 1. Create a new directory for storing the downloaded files. The App Engine run-time requires that the directory be empty before it can download the files to that directory.
  • Step 2. Switch to the directory in cmd to where App Engine is installed on your computer or add it to system variable path.
    It is usually under the following path:C:\Program Files\Google\google_appengine
  • Step 3. Execute the following command to download the project. Remember to replace MyAppName with the ID of your own App Engine project.

    appcfg.py download_app – A MyAppName -V 1 c:\AppEngine\SourceCode

It’ll ask for your Google Account credentials and once authenticated, all the source code files will instantly download to the specified directory. Obviously, you can only download the source code of your own applications from App Engine.

GWT app and hosting it on google appspot



Here I am going to brief about creating a GWT app in Eclipse and hosting it in Google app engine.
here am going to develop a simple game.
Before starting,
You need to install Eclipse, then add GWT toolkit to it, by "Instal new software" option present in Help tab in Eclipse window. Provide url with respect to your eclipse versioin.
Let me tell you a simple point so that you may encourage to use GWT to development. It help to do many logics and calculations on client side, so that performance of system always depends on the processing speed of client machine, not internet or server performance.
Our game logic is: hit the bomb flying over the sky using the rocket.
Create a gwt project with name MyFirstApp, with sample codes in it.
In project tree structure open client package, then open the java file named MyFirstApp.java.
Remove all codes in the class, expect the function name onModuleLode(). Create a class with name Game in same package and extend it with Composit class of gwt.
Write down the code below to that calss
public class Game extends Composite {
HorizontalPanel hp1;
HorizontalPanel hp2;
private VerticalPanel hp;
private Button enemy;
private Button rocket;
private Button fire;

public Game() {
init();
initWidget(hp);
startEnemyAttack();
addListener();
}
private void startEnemyAttack() {

NMorphStyle flyEffect = new NMorphStyle(new Rule(
"start{left: -20px; top: 0px;}"), new Rule(
"end{left: 280px; top: 0px;}"));
flyEffect.setEffectElement(enemy.getElement());
flyEffect.play();
enemyTime.schedule(1800);
}

private void addListener() {
fire.addMouseOverHandler(new MouseOverHandler() {
@Override
public void onMouseOver(MouseOverEvent event) {
fire.setStyleName("mouseOver");
}
});
fire.addMouseOutHandler(new MouseOutHandler() {
@Override
public void onMouseOut(MouseOutEvent event) {
fire.setStyleName("clickfire");
}
});
fire.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
fire.setStyleName("mouseClick");
NMorphStyle flyEffect = new NMorphStyle(newRule("start{left: "
+ rocketPositionX + "px; top: -20px;}"), new Rule(
"end{left: " + rocketPositionX + "px; top: -530px;}"));
flyEffect.setEffectElement(rocket.getElement());
flyEffect.play();
rocketTime.schedule(1800);
}
});
}

Timer enemyTime = new Timer() {
@Override
public void run() {
hp1.remove(enemy);
enemy = new Button();
enemy.setWidth("40px");
enemy.setHeight("40px");
enemy.setStyleName("enemy");
hp1.add(enemy);
startEnemyAttack();
}
};
int hit = 0;
int mis = 0;
int rocketPositionX = 135;
Random r = new Random();
Label score;

Timer rocketTime = new Timer() {
@Override
public void run() {
hp2.remove(rocket);
int temp = enemy.getAbsoluteLeft();
// Window.alert(temp+"<-left:");
if (temp >= rocketPositionX - 20 && temp <= rocketPositionX + 20) {
enemy.setWidth("80px");
enemy.setHeight("80px");
enemy.setStyleName("explosion");
hit++;
}else if(temp >= rocketPositionX - 40 && temp <= rocketPositionX + 40){
if(temp >= rocketPositionX){
System.out.println("rotate left style");
mis++;
}
else{
System.out.println("rotate right style");
mis++;
}
}else {
mis++;
}
rocketPositionX = r.nextInt(280) + 20;
hp.remove(score);
score = new Label("hits: " + hit + " misses: " + mis);
score.setStyleName("score");
hp.add(score);
rocket = new Button();
rocket.setWidth("20px");
rocket.setHeight("50px");
rocket.setStyleName("fire");
String s = rocketPositionX + "px";
rocket.getElement().getStyle().setProperty("left", s);
hp2.add(rocket);
}};

Timer time = new Timer() {
@Override
public void run() {}
};
private void init() {

hp = new VerticalPanel();
hp.setStyleName("launcher");
score = new Label("hits: " + hit + " misses: " + mis);
hp2 = new HorizontalPanel();
hp1 = new HorizontalPanel();
hp1.setWidth("300px");
hp1.setHeight("500px");
hp1.setStyleName("enviorment");
hp.setBorderWidth(1);
enemy = new Button();
enemy.setWidth("40px");
enemy.setHeight("40px");
rocket = new Button();
rocket.setWidth("20px");
rocket.setHeight("50px");
rocket.setStyleName("fire");
enemy.setStyleName("enemy");
fire = new Button();
fire.setWidth("50px");
fire.setHeight("40px");
fire.setStyleName("clickfire");
hp1.add(enemy);
hp2.add(rocket);
hp.add(hp1);
hp.add(hp2);
hp.add(fire);
hp.add(score);
}
public int getHit() {
return hit;
}

public int getMis() {
return mis;
}
public void setHitAndMis() {
hit = 0;
mis = 0;
}
}
now in MyFirstApp add these code inside onModuleLoad() functoin:
Game myGame =new Game();
RootPanel.get().add(myGame);

Thats it.
Right click the project and choose Google, deploy to app Engine,
add your unique id in the settings option. and click ok, if you aree not logged in to the account popup will ask to login to your google account
Now login to appengin of google and check your app url and share it to you friend
Modify your app as your looks and likes. Give Images for best user experience.
http://watertalkshitbomb.appspot.com/ this is the link to the game you developed.
Thanks.
Any queries and doubt regarding this are welcoming...

Strategy for writing test cases (using jUnit and EclEmma)



  1. Write different testing functions for testing different cases with respect to the requirements; validate it with respect to the requirements.
  2. Complexity, Branch and Line coverage, of functions under test, must be 100%.
  3. Method coverage, of class under test, must not be less than the number of methods going to be tested.
  4. Instruction coverage should be greater than or equals to 85%.
  5. Write single test case for each getter and setter functions in entity level.
Though 100 percent test coverage might not be possible still you can always try to reach near it.
  1. Write your test cases in requirement analysis and design phase itself. This way you can ensure all the requirements are testable.
  2. To ensure maximum test coverage divide application into smaller functional modules. Write test cases on such individual unit modules. Also if possible break these modules into smaller parts.
  3. While writing test cases, write test cases for intended functionality first i.e. for valid conditions according to requirements. Then write test cases for invalid conditions. This will cover expected as well unexpected behavior of application under test.
  4. Start testing the application by intend of finding bugs/errors. Don’t think beforehand that there will not be any bugs in the application. If you test the application by intention of finding bugs you will definitely succeed to find those bugs.
  5. Write test cases to all conditions for loops , if-else etc
  6. Use EclEmma for checking test coverage, by using this tool we can analyze coverage for each methods separately. Also will be able to ensure the line coverage and instructions coverage for these methods. This enables us to write more test cases for methods which have low coverage.
Instruction Coverage:
The smallest unit that counts are single Java byte code instructions. Instruction coverage provides information about the amount of code that has been executed or missed.
Branches Coverage:
Branch coverage which is also called as Decision coverage report s the true or false of the conditions like if-else, case and the ternary operator (? :) statements. For an "if" statement, decision coverage will report whether the "if" statement is evaluated in both true and false cases, even if "else" statement doesn't exist.
Line Coverage:
No coverage: No instruction in the line has been executed (red background)
Partial coverage: Only a part of the instruction in the line have been executed (yellow background)
Full coverage: All instructions in the line have been executed (green background)
Line coverage = lines covered / total number of executable lines
Method Coverage:
 A method is considered as executed when at least one instruction has been executed. Each non-abstract method contains at least one instruction. A method is considered as executed when at least one instruction has been executed.
Complexity Coverage:
JaCoCo(Since version 2.0 EclEmma is based on the JaCoCo code coverage library) calculates cyclomatic complexity for each non-abstract method and summarizes complexity for classes, packages and groups. Cyclomatic complexity is the minimum number of paths that can, in (linear) combination, generate all possible paths through a method. Thus the complexity value can serve as an indication for the number of unit test cases to fully cover a certain piece of software. Complexity figures can always be calculated, even in absence of debug information in the class files.
The formal definition of the cyclomatic complexity v(G) is based on the representation of a method's control flow graph as a directed graph:
v(G) = E - N + 2
Where E is the number of edges and N the number of nodes. JaCoCo calculates cyclomatic complexity of a method with the following equivalent equation based on the number of branches (B) and the number of decision points (D):
v(G) = B - D + 1
Based on the coverage status of each branch JaCoCo also calculates covered and missed complexity for each method. Missed complexity again is an indication for the number of test cases missing to fully cover a module. Note that as JaCoCo does not consider exception handling as branches try/catch blocks will also not increase complexity.
Example test coverage report:

GWT composite Component an Example



A Proportion component.

Creating GWT Proportion component

 

public class PropotionComponent extends Composite {

private TextBox numerator = new TextBox();

private TextBox denominator = new TextBox();

private ListBox type = new ListBox();

public static native void alert(String msg) /*-{

$wnd.alert(msg);

}-*/;

private TextBox wholeNumber = new TextBox();

public PropotionComponent(String numeratorValue, String denominatorValue,

String wholeNumberValue) {

HorizontalPanel hp = new HorizontalPanel();

denominator.setStyleName("valueNotInRangeTextBox");

wholeNumber.setStyleName("valueNotInRangeTextBox");

hp.add(type);

hp.add(wholeNumber);

hp.add(numerator);

hp.add(denominator);

wholeNumber.getElement().setAttribute("placeHolder", "whole number");

numerator.getElement().setAttribute("placeHolder", "numerator");

denominator.getElement().setAttribute("placeHolder", "denominator");

type.addItem("ratio");

type.addItem("unitary");

type.addItem("percent");

type.addItem("fraction");

type.addItem("integer fraction");

type.addItem("select type");

initWidget(hp);

// default

wholeNumber.setVisible(false);

denominator.setVisible(false);

numerator.setVisible(false);

type.setItemSelected(5, true);

numerator.addChangeHandler(new ChangeHandler() {

@Override

public void onChange(ChangeEvent event) {

try {

Double.parseDouble(numerator.getValue());

} catch (Exception ex) {

numerator.setValue("");

return;

});

wholeNumber.addChangeHandler(new ChangeHandler() {

@Override

public void onChange(ChangeEvent event) {

try {

Integer.parseInt(wholeNumber.getValue());

} catch (Exception ex) {

wholeNumber.setValue("");

return;

});

denominator.addChangeHandler(new ChangeHandler() {

@Override

public void onChange(ChangeEvent event) {

try {

Double.parseDouble(denominator.getValue());

} catch (Exception ex) {

denominator.setValue("");

return;

});

type.addChangeHandler(new ChangeHandler() {

 

@Override

public void onChange(ChangeEvent event) {

int itemSelected = type.getSelectedIndex();

switch (itemSelected) {

case 0: // ratio

numerator.setValue("");

denominator.setValue("");

wholeNumber.setValue("");

numerator.setVisible(true);

denominator.setVisible(true);

numerator.getElement().setAttribute("placeHolder",

"numerator");

wholeNumber.setVisible(false);

break;

case 1: // unitary, denominator will be 1

numerator.setValue("");

denominator.setValue("");

wholeNumber.setValue("");

numerator.setVisible(true);

wholeNumber.setVisible(false);

numerator.getElement().setAttribute("placeHolder",

"numerator");

denominator.setVisible(false);

break;

case 2: // percentage, denominater is 100

numerator.setValue("");

denominator.setValue("");

wholeNumber.setValue("");

 

wholeNumber.setVisible(false);

denominator.setVisible(false);

numerator.getElement().setAttribute("placeHolder",

"numerator");

numerator.setVisible(true);

break;

case 3: // fraction eg:- 0.23

numerator.setValue("");

denominator.setValue("");

wholeNumber.setValue("");

wholeNumber.setVisible(false);

numerator.setVisible(true);

numerator.getElement().setAttribute("placeHolder",

"fraction");

denominator.setVisible(false);

break;

case 4: // intiger fraction eg:- 1 1/2

numerator.setValue("");

denominator.setValue("");

wholeNumber.setValue("");

wholeNumber.setVisible(true);

numerator.setVisible(true);

numerator.getElement().setAttribute("placeHolder",

"numerator");

denominator.setVisible(true);

break;

case 5: // select type

numerator.setValue("");

denominator.setValue("");

wholeNumber.setValue("");

wholeNumber.setVisible(false);

denominator.setVisible(false);

numerator.setVisible(false);

break;

}

                        }

});

if (!"".equals(numeratorValue)) {

numerator.setValue(numeratorValue);

}

if (!"".equals(wholeNumberValue)) {

denominator.setValue(wholeNumberValue);

}

if (!"".equals(denominatorValue)) {

wholeNumber.setValue(denominatorValue);

}

}

public void setNumerator(String numeratorValue) {

numerator.setValue(numeratorValue);

}

public void setDenominator(String denominatorValue) {

denominator.setValue(denominatorValue);

}

public Double getNumerator() {

if (getType() != 4)

return numerator.getValue() == null ? null : Double

.parseDouble(numerator.getValue());

else

return createNumeratorFromIntegerFraction();

}

private Double createNumeratorFromIntegerFraction() {

if (wholeNumber.getValue() == null || denominator.getValue() == null

|| numerator.getValue() == null) {

return null;

}

return Double.parseDouble(numerator.getValue())

+ (Double.parseDouble(wholeNumber.getValue()) * Double

.parseDouble(denominator.getValue()));

}

public Double getDenominator() {

return denominator.getValue() != null ? Double.parseDouble(denominator

.getValue()) : null;

}

public void setType(int index, boolean selected) {

type.setItemSelected(index, selected);

}

public int getType() {

return type.getSelectedIndex();

}

}