Unit Testing Mocha Framework


#1

I am trying to develop tests for my nativescript application.
The framework i chose was Mocha. It seems to be the better of all the three existing frameworks.
Running the first command that appears on Unit Testing NativeScript Docs:
https://docs.nativescript.org/tooling/testing

Running

tns test init

and selecting Mocha, gives the following error:

C:\Users\MoutaL\Desktop\NativeScript With TypeScript\FastCanteen>tns test init
? Select testing framework: mocha
C:\Users\MoutaL\Desktop\NativeScript With TypeScript\FastCanteen
+-- karma@1.7.0
`-- UNMET PEER DEPENDENCY zone.js@0.8.2

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN @angular/core@4.0.3 requires a peer of zone.js@^0.8.4 but none was installed.
npm WARN nativescript-angular@3.1.3 requires a peer of zone.js@^0.8.4 but none was installed.
C:\Users\MoutaL\Desktop\NativeScript With TypeScript\FastCanteen
+-- karma-mocha@1.3.0
`-- UNMET PEER DEPENDENCY zone.js@0.8.2

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN @angular/core@4.0.3 requires a peer of zone.js@^0.8.4 but none was installed.
npm WARN nativescript-angular@3.1.3 requires a peer of zone.js@^0.8.4 but none was installed.
C:\Users\MoutaL\Desktop\NativeScript With TypeScript\FastCanteen
+-- karma-nativescript-launcher@0.4.0
`-- UNMET PEER DEPENDENCY zone.js@0.8.2

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN @angular/core@4.0.3 requires a peer of zone.js@^0.8.4 but none was installed.
npm WARN nativescript-angular@3.1.3 requires a peer of zone.js@^0.8.4 but none was installed.
npm ERR! registry error parsing json
npm ERR! Windows_NT 10.0.10586
npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install" "karma-chai" "--save-dev"
npm ERR! node v6.11.0
npm ERR! npm  v3.10.10

npm ERR! Unexpected token < in JSON at position 0
npm ERR! <html>
npm ERR! <head>
npm ERR!        <title>Access Denied</title>
npm ERR!        <meta name="author" content="BillYazji" version="082009">
npm ERR!        <meta name="description" content="Error Template">
npm ERR!        <style type="text/css">
npm ERR!                html { font-size:100%; /* IE Hack */ margin:0; padding:0; height:100%; }
npm ERR!                body { font-size:14px; background: #FFFFFF; font-family:  Arial, Verdana, Tahoma, Helvetica; margin:0; padding:0; height:100%; }
npm ERR!                a:link { color: blue; }
npm ERR!                a:visited { color: blue; }
npm ERR!                a:hover { color: blue; }
npm ERR!                a:active { color: blue; }
npm ERR!                #logo { position:absolute; left:30px; top:12px; height:75px; width:75px;        z-index:1; }
npm ERR!                #header {       margin:0; padding:0; height:64px; background:#ed0726; clear:right; border-bottom: 1px solid black;}
npm ERR!                #headtext { position:absolute; left:80px; top:14px; height:50px; font-family:  Arial, Verdana, Tahoma, Helvetica; color: white; font-size: 32px; z-index:0; font-smooth: always; }
npm ERR!                #debug { display:none; }
npm ERR!        </style>
npm ERR!        <script language="javascript" type="text/javascript">
npm ERR!                function ToggleDebug(){
npm ERR!
npm ERR!                        if(document.getElementById("debug").style.display == ""){
npm ERR!                                document.getElementById("debug").style.display = "block";
npm ERR!                        }else{
npm ERR!                                document.getElementById("debug").style.display = "";
npm ERR!                        }
npm ERR!                }
npm ERR!        </script>
npm ERR!
npm ERR! </head>
npm ERR! <body><div> <a name="top"></a>
npm ERR!                <div id="logo"><img src="http://vodafonelogo.vf-pt.internal.vodafone.com/Vodafone.png" alt="&nbsp";></img></div>
npm ERR!                <span id="headtext"><b>Vodafone</b></span>
npm ERR!                <div id="header"></div>
npm ERR! </div>
npm ERR! <div align="right"><span style="background-color:#FFFFFF; padding-left: 2px; padding-right: 2px; padding-bottom: 2px; border:1px solid black;"><a href="javascript:ToggleDebug()">Debug Info</a></span></div>
npm ERR! <br><br>
npm ERR! <center>
npm ERR! <table>
npm ERR!        <tr><td colspan="2" style="color: #C11B17; font-size:32px;"><center><b>Access Denied</b></center></td></tr>
npm ERR!        <tr><td><b>&nbsp;</b></td><td>&nbsp;</td></tr>
npm ERR!        <tr><td><b>Client IP:</b></td><td>10.15.249.33</td></tr>
npm ERR!        <tr><td><b>Username:</b></td><td>moutal&nbsp;</td></tr>
npm ERR!        <tr><td><b>URL:</b></td><td>registry.npmjs.org</td></tr>
npm ERR!        <tr><td><b>Categories:</b>&nbsp;&nbsp;</td><td></td></tr>
npm ERR!        <!--<tr><td><b>Exception:</b></td><td>Your credentials could not be authenticated: "General authentication failure due to bad user ID or authentication token.". You will not be permitted access until your credentials can be verified.</td></tr>-->
npm ERR! </table>
npm ERR! <br>
npm ERR! <div style="width:50%">Your credentials could not be authenticated: "General authentication failure due to bad user ID or authentication token.". You will not be permitted access until your credentials can be verified.<br><br>
npm ERR! </div>
npm ERR! <br>
npm ERR! <br>
npm ERR! <div id="debug"><i>--------- When emailing, select/copy everything below this line ---------</i>
npm ERR! <br><br><br>
npm ERR! <b><u>Detailed Information (debug):</u></b><br>
npm ERR!
npm ERR! <div style="width:60%; display:block;">
npm ERR! <div style="border: 1px dashed blue; padding-left: 20px; padding-right: 20px; padding-top: 10px; padding-bottom: 10px; display: table-cell;">
npm ERR! <table border="0">
npm ERR!        <tr><td colspan="2"><u>Error Specifics</u></td></tr>
npm ERR!        <tr><td>Date:</td><td>08/07/2017 @ 11:34:17</td></tr>
npm ERR!        <tr><td>Proxy ID:</td><td>VFPT-PROXY02-AL</td></tr>
npm ERR!        <tr><td>Conn Type:</td><td>Explicit</td></tr>
npm ERR!        <tr><td>Error ID:</td><td>authentication_failed</td></tr>
npm ERR!        <tr><td>Summary:</td><td>Access Denied</td></tr>
npm ERR!        <tr><td>Details:</td><td>Your credentials could not be authenticated: "General authentication failure due to bad user ID or authentication token.". You will not be permitted access until your credentials can be verified.</td></tr>
npm ERR!        <tr><td>Help:</td><td>This is typically caused by an incorrect username and/or password, but could also be caused by network problems.</td></tr>
npm ERR!        <tr><td>Last Error:</td><td></td></tr>
npm ERR!        <tr><td>Dest IP:</td><td>10.74.50.1</td></tr>
npm ERR!        <tr><td>Method:</td><td>GET</td></tr>
npm ERR!        <tr><td>URL Host:</td><td>registry.npmjs.org</td></tr>
npm ERR!        <tr><td>URL Path:</td><td>/karma-chai</td></tr>
npm ERR!        <tr><td>URL Port:</td><td>80</td></tr>
npm ERR!        <tr><td>HTTP Code:</td><td>401</td></tr>
npm ERR!        <tr><td>Reason:</td><td>Authentication failed either because credentials were not provided or they could not be validated</td></tr>
npm ERR!        <tr><td>Category:</td><td></td></tr>
npm ERR!        <tr><td>Redirect:</td><td></td></tr>
npm ERR!        <tr><td colspan="2"><br><u>User Information</u></td></tr>
npm ERR!        <tr><td>Source IP:</td><td>10.15.249.33</td></tr>
npm ERR!        <tr><td>Username:</td><td>moutal</td></tr>
npm ERR!        <!--<tr><td>User Host:</td><td>10.15.249.33</td></tr>-->
npm ERR!        <tr><td>User Domain:</td><td>LOCAL</td></tr>
npm ERR!        <tr><td>Login Count:</td><td>0</td></tr>
npm ERR!        <tr><td colspan="2"><br><u>SSL Information (if applicable)</u></td></tr>
npm ERR!        <tr><td>S-SSL Hostname:</td><td></td></tr>
npm ERR!        <tr><td>S-SSL Cipher:</td><td>none</td></tr>
npm ERR!        <tr><td>S-SSL Cipher Strength:</td><td> none</td></tr>
npm ERR!        <tr><td>S-SSL Version:</td><td></td></tr>
npm ERR!        <tr><td>S-Socket Error:</td><td></td></tr>
npm ERR!        <tr><td>C-SSL Fail Reason:</td><td></td></tr>
npm ERR!        <tr><td>C-SSL Cipher:</td><td>none</td></tr>
npm ERR!        <tr><td>C-SSL Cipher Strength:</td><td>none</td></tr>
npm ERR!        <tr><td colspan="2"><br><u>DNS Information</u></td></tr>
npm ERR!        <tr><td>DNS Lookup Time:</td><td></td></tr>
npm ERR! </table>
npm ERR! </div>
npm ERR! </div>
npm ERR! <br><br>
npm ERR! <i>--------------------------- End select/copy ---------------------------</i>
npm ERR! <br><br><br>
npm ERR! </div>
npm ERR! </center>
npm ERR! </body>
npm ERR! </html>
npm ERR!
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

npm ERR! Please include the following file with any support request:
npm ERR!     C:\Users\MoutaL\Desktop\NativeScript With TypeScript\FastCanteen\npm-debug.log
Command npm.cmd install karma-chai --save-dev failed with exit code 1
# test init

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Usage   β”‚ Synopsis                                  β”‚
β”‚ General β”‚ $ tns test init [--framework <Framework>] β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Configures your project for unit testing with a selected framework. This operation installs the nativescript-unit-test-runner npm module and its dependencies and creates a tests folder in the app directory.

### Options

    * --framework <Framework> - Sets the unit testing framework to install. The following frameworks are available: jasmine, mocha and qunit.

Any hints?


#2

pinging @nraboy for any help on testing (I think you’ve done tutorials on this?)


#3

Yea i followed the tutorial : https://docs.nativescript.org/tooling/testing
I even finished it and i managed to see it actually working.
But now i am restarting and it is giving me this wierd output…
I managed to run tns the command " tns test init" with some errors in the middle. And running a simple test it displays this on my physical device.


#4

Maybe look at this?:


#5

I already looked at that website. and that was the first tutorial i fully read to try to understand how to do unit Testing.

Well all my code is related to Page Design. Basically all my NativeScript Angular 2 Tests will be related to my UI components with external dependencies. How am i supposed to test that?

I barely have any code since my application is connected to a REST API throught a server that takes of the business part. So i only have basically page components.

How am i supposed to write Unit tests for this component? Can you give a few ideas on how to proceed towards this?

My HomePage, how am i supposed to test it taking into consideration i have external dependencies.

Remenber that i must test the connection between my application and a Spring Boot Server. That’s the part i dont know neither have any idea on how to do it.

Any ideas?

My code:

HomePage.html

<FlexboxLayout flexDirection="column">
        <AbsoluteLayout>
    <image class="imageRhombus" src="res://rhombus" stretch="enum"></image>
  </AbsoluteLayout>
    <label class="text-title" text="FastCanteen"></label>
    <StackLayout orientation="vertical" flexGrow="1" backgroundColor="transparent">
        <StackLayout marginTop="20" marginBottom="30">
            <image class="imageAccountCircle" src="res://ic_account_circle_white"></image>
            <Label id="userNameTop" class="labelName" textWrap="true"></Label>
            <Label class="labelNIF" [text]=user.nif textWrap="true"></Label>
        </StackLayout>
        <StackLayout>
            <StackLayout marginLeft="70" marginRight="70" marginBottom="60" backgroundColor="#444444" borderRadius="30%" opacity="0.7"
                height="100">
                <Label id="balance" class="labelBalanceValue"></Label>
                <Label class="labelTextBalance" text="Available Balance"></Label>
            </StackLayout>
        </StackLayout>
        <div *ngIf="isVisible">
            <StackLayout (tap)="accountTransactions()" [nsRouterLink]="['/main']" pageTransition="slide" marginBottom="10" marginLeft="20"
                marginRight="20" verticalAlignment="bottom" backgroundColor="#444444">
                <GridLayout rows="auto auto auto" columns="* 75">
                    <Label class="labelLastBill" text="Last Bill" textWrap="true" row="0" col="0" marginTop="10"></Label>
                    <Label id="valueLastBill" class="labelValue" textWrap="true" row="1" col="0"></Label>
                    <Label class="transactionsButtons" text=">" row="1" col="1" marginTop="-5"></Label>
                    <Label id="typeLastBill" class="labelTypeOfBill" textWrap="true" row="2" col="0" marginBottom="10"></Label>
                </GridLayout>
            </StackLayout>
        </div>
    </StackLayout>
    <FlexboxLayout>
        <BottomBar row="1" [items]="items" [hide]="hidden" [titleState]="titleState" (loaded)="tabLoaded($event)" (tabSelected)="tabSelected($event)"
            [inactiveColor]="inactiveColor" [accentColor]="accentColor" colored="true"></BottomBar>
    </FlexboxLayout>
</FlexboxLayout>

HomePage.component.ts

import { Page } from "ui/page";
import { Component, OnInit } from "@angular/core";
import { registerElement } from 'nativescript-angular';
import { BottomBar, BottomBarItem, TITLE_STATE, SelectedIndexChangedEventData, Notification } from 'nativescript-bottombar';
import { User } from "../../shared/model/user/user";
import { UserService } from "../../shared/model/user/user.service";
import { MovementService } from "../../shared/model/movement/movement.service";
import { Router, NavigationExtras } from "@angular/router";
import * as colorModule from "tns-core-modules/color";
import { ActivatedRoute } from "@angular/router";
import * as platformModule from "tns-core-modules/platform";
import { Config } from "../../shared/config";
import { Budget } from "../../shared/model/budget/budget";
import listView = require("ui/list-view");
import { Http } from "@angular/http";
var view = require("ui/core/view");
var applicationSettings = require("application-settings");

registerElement('BottomBar', () => BottomBar);

@Component({
    selector: "homePage",
    providers: [UserService, MovementService],
    templateUrl: "pages/homePage/homePage.html",
    styleUrls: ["pages/homePage/homePage-common.css", "pages/homePage/homePage.css"]
})
export class HomePageComponent implements OnInit {
    public hidden: boolean;
    public titleState: TITLE_STATE;
    public _bar: BottomBar;
    public inactiveColor: string;
    public accentColor: string;
    public user: User;
    public budget: Budget;
    public nameFromAPI: string;
    public value: string;
    public type: string;
    public isVisible: boolean = true;;
    public height: number;
    public width: number;


    constructor(private http: Http, private router: Router, private page: Page, private route: ActivatedRoute, private userService: UserService, private movementService: MovementService) {
        this.route.queryParams.subscribe(params => {
            this.user = JSON.parse(params["user"]);
        })
        console.log("Inside HomePage");
        console.log("UserToken: " + Config.token);
        this.user.name = this.nameFromAPI;
    }


     public items: Array<BottomBarItem> = [
        new BottomBarItem(0, "Home", "ic_home", "white"),
        new BottomBarItem(1, "Menu", "ic_local_dining", "white"),
        new BottomBarItem(2, "Check-out", "ic_add_a_photo", "white"),
        new BottomBarItem(3, "Transactions", "ic_assignment", "white"),
        new BottomBarItem(4, "Settings", "ic_settings", "white")
    ];

    tabLoaded(event) {
        this._bar = <BottomBar>event.object;
        this.hidden = false;
        this.titleState = TITLE_STATE.ALWAYS_SHOW;
        var Color = colorModule.Color;
        var color = new Color("#8e8e93");
        this.inactiveColor = color.hex;
        this.accentColor = "black";
    }

    ngOnInit() {
        let navigationExtras: NavigationExtras = {
            queryParams: {
                "user": JSON.stringify({
                    "name": this.user.name,
                    "nif": this.user.nif,
                    "password": this.user.password
                })
            }
        };
        this.page.actionBarHidden = true;
        this.page.backgroundImage = "res://bitmap";

        // Available Balance
        this.budget = new Budget();
        var tmp;
        
        this.userService.readBalance(applicationSettings.getString("user.token", "default"))
            .subscribe((res) => {
                this.budget.amount = res;
                tmp = res;
                //console.log("Budget Value on Home Page : " + this.budget.amount);
                var htmlBalance;
                htmlBalance = this.page.getViewById("balance");
                if (typeof htmlBalance == "undefined") {
                    alert("Balance undefined!");
                } else {
                    if (Number.isInteger(this.budget.amount)) {
                        htmlBalance.text = this.budget.amount + ".00 €";
                    } else {
                        var number = this.decimalPlaces(this.budget.amount);
                        if (number == 1) {
                            htmlBalance.text = this.budget.amount + "0 €";
                        } else {
                            htmlBalance.text = this.budget.amount + "€";
                        }
                    }

                }
            },
            (error) => alert(error)
            );

        var htmlBalance;
        htmlBalance = this.page.getViewById("balance");
        htmlBalance.text = "50.00 €";
        //NameByToken
        this.userService.nameByToken(applicationSettings.getString("user.token", "default"))
            .subscribe((res) => {
                this.nameFromAPI = res.Result.message;
                //console.log("Username on Home Page[From Method] : " + res.Result.message);
                var htmlName;
                htmlName = this.page.getViewById("userNameTop");
                if (typeof htmlName == "undefined") {
                    alert("Name undefined!");
                } else {
                    htmlName.text = this.nameFromAPI;
                }
            },
            (error) => alert(error)
            );
        var htmlName;
        htmlName = this.page.getViewById("userNameTop");
        htmlName.text = "Joao";
//LastMovemnet
this.movementService.lastMovement(applicationSettings.getString("user.token", "default"))
    .subscribe((res) => {
        this.value = res.Value;
        this.type = res.Type;
        //verificar que values nao vem a null
        if (this.type != "undefined" && this.value != "undefined") {
            this.isVisible = true;

            var htmlValueLastBill;
            htmlValueLastBill = this.page.getViewById("valueLastBill");
            if (typeof htmlValueLastBill == "undefined") {
                alert("Value undefined!");
            } else {
                htmlValueLastBill.text = "- € " + this.value;
            }

            //Portuguese -> English
            this.type = this.type.trim();
            if (this.type == "Pagamento") {
                this.type = "Payment";
            }
            if (this.type == "Carregamento") {
                this.type = "Bank Transaction";
            }
            if (this.type == "Estorno") {
                this.type = "Refund";
            }


            var htmlTypeLastBill;
            htmlTypeLastBill = this.page.getViewById("typeLastBill");
            if (typeof htmlTypeLastBill == "undefined") {
                alert("Type undefined!");
            } else {
                htmlTypeLastBill.text = this.type;
            }
        } else {
            this.isVisible = false;
        }

    },
    (error) => alert(error)
    );
    }

    decimalPlaces(num) {
        var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
        if (!match) { return 0; }
        return Math.max(
            0,
            // Number of digits right of decimal point.
            (match[1] ? match[1].length : 0)
            // Adjust for scientific notation.
            - (match[2] ? +match[2] : 0));
    }

    accountTransactions() {
        let navigationExtras: NavigationExtras = {
            queryParams: {
                "user": JSON.stringify({
                    "name": this.user.name,
                    "nif": this.user.nif,
                    "password": this.user.password
                })
            }
        };
        this.router.navigate(["/transactions"], navigationExtras);
    }

    tabSelected(args: SelectedIndexChangedEventData) {
        switch (args.newIndex) {
            case 0: {
                let navigationExtras: NavigationExtras = {
                    queryParams: {
                        "user": JSON.stringify({
                            "name": this.user.name,
                            "nif": this.user.nif,
                            "password": this.user.password
                        })
                    }
                };
                this.router.navigate(["/homePage"], navigationExtras);
                break;
            }
            case 1: {
                let navigationExtras: NavigationExtras = {
                    queryParams: {
                        "user": JSON.stringify({
                            "name": this.user.name,
                            "nif": this.user.nif,
                            "password": this.user.password
                        })
                    }
                };
                this.router.navigate(["/menu"], navigationExtras);
                break;
            }
            case 2: {
                let navigationExtras: NavigationExtras = {
                    queryParams: {
                        "user": JSON.stringify({
                            "name": this.user.name,
                            "nif": this.user.nif,
                            "password": this.user.password
                        })
                    }
                };
                this.router.navigate(["/payment"], navigationExtras);
                break;
            }
            case 3: {
                let navigationExtras: NavigationExtras = {
                    queryParams: {
                        "user": JSON.stringify({
                            "name": this.user.name,
                            "nif": this.user.nif,
                            "password": this.user.password
                        })
                    }
                };
                this.router.navigate(["/transactions"], navigationExtras);
                break;
            }
            case 4: {
                let navigationExtras: NavigationExtras = {
                    queryParams: {
                        "user": JSON.stringify({
                            "name": this.user.name,
                            "nif": this.user.nif,
                            "password": this.user.password
                        })
                    }
                };
                this.router.navigate(["/userSettings"], navigationExtras);
                break;
            }

        }
    }
}

@nraboy.

Thanks in advance


#6

I was reading all morning on the NativeScript Docs.
According to the NativeScript Docs,

"
When creating tests for a new or existing functionality, keep in mind the following limitations.

  • You cannot require the file or module in which application.start() is called.
  • You cannot use more than one testing framework per project.
  • You cannot test styling and UI which are not applied or created via JavaScript."

Taking into consideration i wrote my code in TypeScript + Angular 2, i will not be able to test my styling and UI since they were not created via JavaScript. Is this correct?
Althought every typescript file i create generates a Javascript compiled code file. I could do tests on that JavaScript compiled code file. Am i thinking in the right way or not?
@rhanb @jen.looper


#7

It is best you don’t write unit tests in your NativeScript app to test your API. You should write unit tests for your web application if you want to test that.

Instead, you should create mock data in your NativeScript app based on the API spec and test against that.

Unit tests aren’t for UI. I mean what would you realistically test for within a UI? I believe you’d want integration tests for that.

You might want to take a step back and try to learn Mocha or Jasmine before trying to use them in your NativeScript app.

Best,


#8

I believe you’re right. I feel unprepared regarding this subject of Testing.

Althought from what you’ve wrote and from what i learnt so far i think i will follow the following approach:

There are several types of Testing you can do. There are unit tests, functional tests, integration tests, regression tests etc…

I was planning on doing integrational tests for my NativeScript APP.
But following now your approach which seems good, i will create mock data to replace the response from my server. I will compare my UI data against the mock data. I will still call them integrational tests instead of unit tests since i am still testing software modules that are connected.

Regarding the Server i will write unit tests for it.

But still a question rises up, since my application is TypeScript + Angular and i only have User Interface Code, most of what i have regarding β€œcode” are the connection to the server and the catch of results and the validations of the results. I dont really have any domain/business code related on my app to test.
So what do i test on my Application?
Taking into account i have this limitation, β€œYou cannot test styling and UI which are not applied or created via JavaScript.”.
@nraboy


#9

Hi @PurpleRune,

You can test UI with TypeScript and Angular, but you have to create your UI programatically to be able to test it, you can"t test UI from XML actually. (TypeScript compiles to JavaScript so no differences)

You can also take a look at Appium for UI testing, but you’ll have to integrate there SDK for iOS and Android in your project.

On your app side you shouldn’ have to test your API since you should implement them on the server side. But you can still test the result you’re retreiving.
On the front side you should tests as much functionnality as you can without the UI, but as an API you can also test endpoints, but for your app instead of testing through a request to an url, you directly interact with the interface through your tests.
Hope I’m clear


#10

Hey @rhanb
I understood everything except the first phrase.
How do i create my UI programatically to be able to test it?

Thanks for the answer it all made sense.


#11

For example:

function createDynamicLabel () {
    let label = new Label();
    label.text = "dynamic";
    return label;
}
// for example you can implement a test that except the function to return a label with a text equals to "dynamic"

#12

Alright makes sense what you said. But taking into consideration my case now.

Speaking not in general senses but in my own particular case.

All my styling is on CSS and all my UI design is on XML.
Since i dont have any XML declared via Typescript i can’t test my UI. Correct?


#13

Well you won"t be able to directly test the UI as in a web app using Karma, except if you integrate Appium. But maybe you can create unit test that programmatically retrieve your UI elements and then test the value of it after different action that you launch programmatically.
So you can"t directly test the UI, because it would mean to simulate user interaction with your app wich you can’t do as you would in an Angular wep app with Karma ! :slight_smile: