Professional Documents
Culture Documents
Master of Technology
In
Software Engineering
by
Darsi Kapil
Register Number
14MSE0032
Under the guidance of
Prof.Magesh G
Assistant Professor(Junior)
School of Information Technology and Engineering
VIT, Vellore.
April, 2019
1
DECLARATION
I hereby declare that the thesis entitled “Test Automation Framework for
Philips SmartSleep and Philips Somneo” by me, for the award of the degree of
Professor(Junior)).
I further declare that the work reported in this thesis has not been submitted and
will not be submitted, either in part or in full, for the award of any other degree
Place : Vellore
Date : Signature of the Candidate
2
CERTIFICATE
This is to certify that the thesis entitled “Test Automation Framework for
Philips SmartSleep and Philips Somneo” submitted by “Darsi Kapil,
14MSE0032”, School of Information Technology and Engineering, VIT
University, for the award of the degree of Master of Technology in Software
Engineering, is a record of bonafide work carried out by him under my
supervision during the period, 01. 12. 2018 to 30.04.2019, as per the VIT code of
academic and research ethics. The contents of this report have not been submitted
and will not be submitted either in part or in full, for the award of any other degree
or diploma in this institute or any other institute or university. The thesis fulfils
the requirements and regulations of the University and in my opinion meets the
necessary standards for submission.
Place : Vellore
Date : Signature of the Guide
Head of Department
3
INDUSTRY CERTIFICATE
This is to certify that the thesis entitled “Test Automation Framework for Philips
SmartSleep and Philips Somneo” submitted by “Darsi Kapil, 14MSE0032”, School
of Information Technology and Engineering, VIT University, for the award of the
degree of Master of Technology in Software Engineering, is a record of bonafide
work carried out by him under my supervision during the period, 02.08.2018 –
Current Date, as per the Philips Business Principles and Guidelines. The contents
of this report have not been submitted and will not be submitted either in part or
in full, for the award of any other degree or diploma in this institute or any other
institute or university. The thesis fulfils the requirements and regulations of the
University and in my opinion meets the necessary standards for submission.
Place : Vellore
Date : Signature of the Mentor
4
TABLE OF CONTENTS
CHAPTER NO. TITLE PAGE NO.
1. INTRODUCTION 7
1.1.Problem Statement 7
1.2.Motivation 7
1.3.Objective 7
2. TECHNOLOGIES LEARNT 8
2.1 SeeTest Automation 8
2.2 Specflow 8
2.3 Jenkins 10
2.4 SourceTree 12
3. PRODUCT INFORMATION 12
3.1 Philips Smartsleep 12
3.2 Philps Somneo 13
3.3 Philips SleepMapper Application 15
3.3.1 Application User Interface 16
3.3.2 Application Splash Screen/Launch Screen 16
3.3.3 Product Selection Screen 16
3.3.4 Wi-Fi Set-up screen for Philips Somneo 17
3.3.5 Bluetooth Setup for Philips SmartSleep 18
3.3.6 Bluetooth Device Discovery Screen 19
3.3.7 Sleep Data Screen 19
4. IMPLEMENTATION 20
4.1 HiggsTest.py 20
4.2 UserRegistration.Feature 25
4.3 UserRegistration.cs 25
4.4 AppLaucher.cs 26
4.5 ConfigurationManager.cs 30
4.6 Hooks.cs 34
5
4.7 PowerSleepDevice.cs 36
4.8 ScenarioContext.cs 38
4.9 ScreenFlow.cs 40
6. RESULTS AND DISCUSSIONS 42
7. CONCLUSION AND FUTURE WORK 42
7.1 Conclusion 42
7.2 Future Work 42
6
1 . INTRODUCTION
Although occasional sleep interruptions are generally no more than a nuisance, ongoing
lack of sleep can lead to excessive daytime sleepiness, emotional difficulties, poor job
performance, Obesity and a lowered perception of quality of life.
1.2. Motivation
Millions of people know that sleep is critical to their health, and are searching for ways
to get better rest. From identifying individual sleep needs to offering clinically proven
solutions, Philips is on a mission to make better sleep a reality for everyone. For 35 years,
Philips has developed revolutionary sleep products rooted in clinical evidence and data-driven
insights, making them the proud leader in sleep innovation. Their portfolio continues to grow
– and are expanding their reach in order to help people everywhere sleep better and live happier,
healthier lives.
1.3. Objective
Our main objective is develop a automation framework using SeeTest Automation
which could help to automate the test cases and then integrate them into the Jenkins CI and run
the automation script on a nightly basis to see if there is any flaw in the build or the automation
script.
7
2.TECHNOLOGIES INVOLVED
In general, the process of working with SeeTest Automation mobile testing begins with
connecting either a physical mobile device or a corresponding emulator (on-site cloud
configuration is also available). Once connected, you can record and edit scripts which will
perform a specific test scenario. When each script is complete, you can play it, evaluate the
generated execution report, and export the selected test code to any testing framework that
you regularly use. SeeTest Automation , Supports many test frameworks including; UFT,
TestComplete, RFT, C#, JUnit, Python, and Perl. From each of these, you can perform
additional editing prior to running each test. Then simply execute the test, and review the
reports generated by each individual framework. Cover mobile performance testing and
functional testing all at once. Run your existing mobile automated test cases under different
network, device and load conditions. Define and inject different network profiles to your
tests. Simulate different parameters such as the geographical location of a user, server and
network type (3G,4G, LTE,etc.) Make sure your app does not overly consume device
resources or crashes mobile devices by checking the usage levels of critical features such as
CPU, memory, battery. Run your mobile test automation suites under different load
conditions by integrating with HP LoadRunner.
2.2 Specflow:
We use SpecFlow to define, manage and automatically execute human-readable acceptance
tests in .NET projects. Writing easily understandable tests is a cornerstone of the BDD
paradigm and also helps build up a living documentation of your system.
SpecFlow is open source and provided under a BSD license. As part of the Cucumber family,
SpecFlow uses the official Gherkin parser and supports the .NET framework, Xamarin and
Mono.
SpecFlow integrates with Visual Studio, but can be also used from the command line (e.g. on
a build server). SpecFlow supports popular testing frameworks: MSTest, NUnit (2 and 3) and
xUnit 2.
8
SpecFlow+ adds additional functionality to SpecFlow, such as Visual Studio Test Explorer
integration, a dedicated test runner with advanced test execution options, execution reports
(HTML, XML, JSON) and much more.
1) Specify
Describe the behavior of your system using human-readable syntax. Define specifications in
the problem domain using the language of your stakeholders and build up a living
documentation of your system.
Fig 2.1
2) Automate
Bind your test specifications to your application code to automate the testing of your system.
9
Fig 2.2
3) Execute
Execute the test cases and integrate them into the Jenkins CI server.
2.3 Jenkins:
Jenkins is a self-contained, open source automation server which can be used to automate all
sorts of tasks related to building, testing, and delivering or deploying software.
Jenkins can be installed through native system packages, Docker, or even run standalone by
any machine with a Java Runtime Environment (JRE) installed.
Pipelines are made up of multiple steps that allow you to build, test and deploy applications.
Jenkins Pipeline allows you to compose multiple steps in an easy way that can help you model
any sort of automation process. Think of a "step" like a single command which performs a
single action. When a step succeeds it moves onto the next step. When a step fails to execute
correctly the Pipeline will fail. When all the steps in the Pipeline have successfully completed,
the Pipeline is considered to have successfully executed.
10
Fig 2.3
2.4 SourceTree:
Version control systems are a category of software tools that help a software team manage
changes to source code over time. Version control software keeps track of every modification
to the code in a special kind of database. If a mistake is made, developers can turn back the
clock and compare earlier versions of the code to help fix the mistake while minimizing
disruption to all team members.
For almost all software projects, the source code is like the crown jewels - a precious asset
whose value must be protected. For most software teams, the source code is a repository of
the invaluable knowledge and understanding about the problem domain that the developers
have collected and refined through careful effort. Version control protects source code from
both catastrophe and the casual degradation of human error and unintended consequences.
Software developers working in teams are continually writing new source code and changing
existing source code. The code for a project, app or software component is typically
organized in a folder structure or "file tree". One developer on the team may be working on a
new feature while another developer fixes an unrelated bug by changing code, each developer
may make their changes in several parts of the file tree.
11
Fig 2.4
3.PRODUCT INFORMATION
It monitors your level of sleep from moment to moment and responds in real time.Every night,
our proprietary algorithm customizes the timing and volume of tones to your sleep
pattern.Volume is controlled not to wake you up, and Bluetooth and Wi-Fi are off when device
is being worn.Every morning, the SleepMapper App will show you your sleep metrics and your
sleep boost score. The Total Sleep Score is an aggregate of several dimensions of your sleep.
It includes the total amount of time that you sleep, how long it takes you to fall asleep, the
number of awakenings that occur while you sleep and the Sleep Boost. Each component value
12
is either adding to or detracting from your best sleep. We help you to see where this is occurring
so that you can actively manage to improve your sleep quality. Getting more total sleep is your
best bet to improving your overall total sleep score.
Fig 2.5
13
Fig 2.6
14
3.3. Philips SleepMapper Application
Philips SleepMapper Application was developed to control the SmartSleep and Somneo
devices by improving the usability of the devices.
15
3.3. Application User Interface
16
3.3.2. Launch Screen and Login Screen
17
3.3.4 WiFi Setup for Philips Somneo Screen
18
3.3.6 Discover Devices Screen for Philips SmartSleep
19
4.IMPLEMENTATION OF THE FRAMEWORK
import os
import tempfile
import numpy as np
import pandas as pd
import tensorflow as tf
# pylint: disable=g-bad-import-order
tf.logging.set_verbosity(tf.logging.ERROR)
class BaseTest(tf.test.TestCase):
@classmethod
super(BaseTest, cls).setUpClass()
train_higgs.define_train_higgs_flags()
def setUp(self):
20
self.data_dir = self.get_temp_dir()
data = pd.read_csv(
).as_matrix()
tmpfile = tempfile.NamedTemporaryFile()
np.savez_compressed(tmpfile, data=data)
tf.gfile.Copy(tmpfile.name, self.input_npz)
def test_read_higgs_data(self):
self.data_dir + "non-existing-path",
self.data_dir,
def test_make_inputs_from_np_arrays(self):
21
"""Tests make_inputs_from_np_arrays() function."""
train_data, _ = train_higgs.read_higgs_data(
self.data_dir,
(input_fn, feature_names,
feature_columns) = train_higgs.make_inputs_from_np_arrays(
# Check feature_names.
self.assertAllEqual(feature_names,
self.assertEqual(28, len(feature_columns))
bucketized_column_type = type(
tf.feature_column.bucketized_column(
tf.feature_column.numeric_column("feature_01"),
self.assertIsInstance(feature_column, bucketized_column_type)
# At least 2 boundaries.
self.assertGreaterEqual(len(feature_column.boundaries), 2)
# Tests that the source column names of the bucketized columns match.
self.assertAllEqual(feature_names,
22
# Check features.
self.assertIsInstance(features, dict)
self.assertAllEqual(feature_names, sorted(features.keys()))
self.assertAllClose(
np.squeeze(features[feature_names[0]], 1))
self.assertAllClose(
np.squeeze(features[feature_names[10]], 1))
def test_end_to_end(self):
integration.run_synthetic(
"--data_dir", self.data_dir,
23
"--model_dir", model_dir,
"--n_trees", "5",
"--train_start", "0",
"--train_count", "12",
"--eval_start", "12",
"--eval_count", "8",
],
synth=False, max_train=None)
self.assertTrue(tf.gfile.Exists(os.path.join(model_dir, "checkpoint")))
def test_end_to_end_with_export(self):
integration.run_synthetic(
"--data_dir", self.data_dir,
"--model_dir", model_dir,
"--export_dir", export_dir,
"--n_trees", "5",
"--train_start", "0",
"--train_count", "12",
"--eval_start", "12",
"--eval_count", "8",
],
synth=False, max_train=None)
24
self.assertTrue(tf.gfile.Exists(os.path.join(model_dir, "checkpoint")))
self.assertTrue(tf.gfile.Exists(os.path.join(export_dir)))
if __name__ == "__main__":
tf.test.main()
4.2 UserRegistration.feature
Feature: UserRegistration
In order to be able to use Philips services
As a Healthy Sleep User
I want to be able to create and log in to a Philips account
Background:
@UserRegistrationLogIn
Scenario: Log in with existing account
Given the app is freshly installed
And the app is started
And I am on screen 'UserRegistration'
When I press the button 'Philips account'
Then I should see the text 'Log in'
When I enter text 'deku@mailinator.com' in the field 'Your email or phone
number'
And I enter text 'password123' in the field 'Enter password'
And I click the text 'deku@mailinator.com'
When I press the button 'Log In'
Then I should wait for UserRegistration to login
When I press the button 'I accept the Terms and Conditions'
And I press the button 'Continue’
Then I should go to the next screen
4.3 UserRegistration.cs
using System;
using TechTalk.SpecFlow;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PowerSleep_TestAutomation.Framework;
using PowerSleep_TestAutomation.Framework.SeeTest;
namespace PowerSleep_TestAutomation.StepDefinitions
{
[Binding]
public class UserRegistrationSteps : Steps
{
private static string SUBTITLE_FIELD = "UserRegistration LogIn SubTitle";
private static string COUNTRY_SELECT = "Country Selection";
25
[Then(@"I should wait for UserRegistration to login")]
public void ThenIShouldWaitForUserRegistrationToLogIn()
{
string zone =
(string)ScenarioContext.Current[ScenarioContextKeys.CURRENT_SCREEN];
var client = SeeTestClientManager.GetClient();
if (ConfigurationManager.Instance.TargetIsIOS())
{
Then(@"I should wait for 3 seconds");
string query = QueryBuilder.XPath().Equals().Text(myCountry).Build();
if (Element.Exists(query, DynamicRecognition.NATIVE))
{
When(@"I click the text '" + myCountry + "'");
}
}
}
26
{
When(@"I press the button 'Continue'");
Then(@"I should wait for 10 seconds");
}
Then(@"I should wait for 5 seconds");
}
Then(@"I should go to the next screen");
}
[Given(@"Creating a new account")]
public void NewUserRegistration(string email)
{
When(@"I am on screen 'UserRegistration'");
When(@"I press the button 'Create my Philips account'");
When(@"I enter text 'test' in the field
'usr_createScreen_firstName_textField'");
When(@"I enter text "+email+"in the field
'usr_createscreen_emailormobile_textfield'");
When(@"I enter text 'password123' in the field
'usr_createScreen_password_textField'");
When(@"I press the button 'Accepting Apps Terms and Conditions'");
When(@"I scroll 'Down'");
Then(@"I should see the button 'Create my Philips account'");
When(@"I press the button 'Create my Philips account'");
Then(@"I should go to the next screen");
Then(@"I should see the text 'Confirm your email'");
}
public void NewUserRegistrationUnhappyFLow(String mail)
{
When(@"I am on screen 'UserRegistration'");
When(@"I press the button 'Create my Philips account'");
When(@"I enter text 'test' in the field
'usr_createScreen_firstName_textField'");
When(@"I enter text "+mail+ " in the field
'usr_createscreen_emailormobile_textfield'");
When(@"I enter text 'password123' in the field
'usr_createScreen_password_textField'");
When(@"I press the button 'Accepting Apps Terms and Conditions'");
When(@"I scroll 'Down'");
Then(@"I should see the button 'Create my Philips account'");
When(@"I press the button 'Create my Philips account'");
Then(@"I should go to the next screen");
Then(@"I should see the text 'Confirm your email'");
Then(@"I should see the text 'Your Email is already registered");
}
}
}
4.4 AppLauncher.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PowerSleep_TestAutomation.Util;
using TechTalk.SpecFlow;
27
namespace PowerSleep_TestAutomation.Framework
{
public class AppLauncher
{
private static bool clearAppData = false;
public AppLauncher() { }
28
string package =
ConfigurationManager.Instance.GetStringConfigurationPropertyForTargetPlatform(Configur
ationManager.HSS_APP_PACKAGE);
string activity =
ConfigurationManager.Instance.GetStringConfigurationPropertyForTargetPlatform(Configur
ationManager.HSS_APP_LAUNCH_ACTIVITY);
string activityURL = package + "/" + activity;
client.DeviceAction("Home");
client.Launch(activityURL,true, stopIfRunning);
}
client.Install(package, true);
}
client.ApplicationClose(package);
}
if (ConfigurationManager.Instance.TargetIsAndroid())
{
appPath =
ConfigurationManager.Instance.GetRepositoryPathFor(@"Scripts\HSS.apk");
29
}
if (ConfigurationManager.Instance.TargetIsIOS())
{
appPath =
ConfigurationManager.Instance.GetRepositoryPathFor(@"Scripts\HSS.ipa");
}
4.5 ConfigurationManager.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using PowerSleep_TestAutomation.Framework.Cloud;
namespace PowerSleep_TestAutomation.Framework
{
public class ConfigurationManager
{
private static string HSS_EXT_CONFIG_DIR = "HSS_EXT_CONFIG_DIR";
private static string HSS_TARGET_PLATFORM = "HSS_TARGET_PLATFORM";
#if _IOS_DEFAULT_PLATFORM
private static string HSS_DEFAULT_PLATFORM = "ios";
#else
private static string HSS_DEFAULT_PLATFORM = "android";
#endif
#region ConfigurationProperties
public static string ST_CLIENT_HOST = "st_client_host";
public static string ST_CLIENT_PORT = "st_client_port";
public static string ST_CLIENT_USE_SESSION_ID = "st_client_use_session_id";
30
public static string HSS_APP_PACKAGE = "hss_app_package";
public static string HSS_APP_LAUNCH_ACTIVITY = "hss_app_launch_activity";
public static string HSS_TARGET_DEVICE = "hss_target_device";
public static string HSS_EXECUTING_COUNTRY = "hss_executing_country";
#region SingletonPattern
private static ConfigurationManager instance;
private ConfigurationManager()
{
Init();
}
31
return platform;
}
32
public string GetStringConfigurationProperty(string propertyKey)
{
return (string)GetConfigurationProperty(this.configObject, propertyKey);
}
33
foreach (JToken accountToken in accountArray)
{
User user = new User(accountToken);
users.Add(user);
}
return users;
}
4.6 Hooks.cs
using System;
using PowerSleep_TestAutomation.Framework.SeeTest;
using TechTalk.SpecFlow;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.IO;
namespace PowerSleep_TestAutomation.Framework
{
[Binding]
34
public class Hooks
{
[BeforeScenario]
public void BeforeScenario()
{
// Check if we are running platform specific scenario on wrong
configuration
DoPlatformAndBuildConfigMatch();
ConfigurationManager.Instance.GetPowerSleepDevice(deviceId).PowerOff();
}
SeeTestClientManager.Instance.CreateClient();
}
[AfterScenario]
public void AfterScenario()
{
if (false & ScenarioContext.Current.TestError != null) // deactivated
{
// Test failed, take screenshot
SeeTestClientManager.Instance.Client.Capture();
// Create filename
string featureTitle = FeatureContext.Current.FeatureInfo.Title;
string scenarioTitle = ScenarioContext.Current.ScenarioInfo.Title;
string time = DateTime.Now.ToString("s");
string fileName = String.Format("{0}_{1}_{2}.png", featureTitle,
scenarioTitle, time);
[AfterStep]
public void AfterStep()
{
// check if SeeTest Internal Exception occurred, mark as inconclusive
result
Exception exception = ScenarioContext.Current.TestError;
if (ErrorAnalysis.IsSeeTestError(exception))
35
{
Assert.Inconclusive(exception.Message);
}
}
4.7 PowerSleepDevice.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using PowerSleep_TestAutomation.Util;
using System.Threading;
namespace PowerSleep_TestAutomation.Framework
{
public class PowerSleepDevice
{
private string id = null;
private string mac = null;
private string usbPort = null;
private string ios_id = null;
private string comPort = null;
private string name = null;
36
this.name = name;
}
public string ID
{
get { return id; }
}
37
{
if (!String.IsNullOrEmpty(comPort))
{
PowerSleep.DeviceControl deviceControl =
PowerSleep.DeviceControl.Instance;
deviceControl.Open(comPort);
deviceControl.FactoryReset();
deviceControl.Close();
}
}
// Send Session
deviceControl.AddSession(session);
deviceControl.Close();
}
}
4.8 ScenarioContext.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PowerSleep_TestAutomation.Framework
{
public class ScenarioContextKeys
{
public static string CURRENT_SCREEN = "tfw_current_screen";
}
}
SeeTestClientManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
38
using System.Text;
using System.Threading.Tasks;
using experitestClient;
namespace PowerSleep_TestAutomation.Framework
{
public class SeeTestClientManager
{
#region SingletonPattern
private static SeeTestClientManager instance;
private SeeTestClientManager()
{
}
currentClient.SetProjectBaseDirectory(ConfigurationManager.Instance.GetRepositoryPathF
or(ConfigurationManager.HSS_SEETEST_OBJECT_REPOSITORY_DIRNAME));
currentClient.SetReporter("xml",
ConfigurationManager.Instance.GetRepositoryPathFor(ConfigurationManager.HSS_SEETEST_RE
PORT_DIRNAME), "HSS_TestAutomation");
currentClient.SetShowImageInReport(false);
currentClient.SetDevice(deviceId);
if (ConfigurationManager.Instance.TargetIsIOS())
{
currentClient.SetProperty("ios.elementsendtext.action.fire", "true");
}
}
39
// Generates a report of the test case.
// For more information -
// https://docs.experitest.com/display/public/SA/Report+Of+Executed+Test
currentClient.GenerateReport(false);
currentClient.ApplicationClose(ConfigurationManager.Instance.GetStringConfigurationPro
pertyForTargetPlatform(ConfigurationManager.HSS_APP_PACKAGE));
// Releases the client so that other clients can approach the agent in
// the near future.
currentClient.ReleaseClient();
}
4.9 ScreenFlow.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json.Linq;
namespace PowerSleep_TestAutomation.Framework
{
public class ScreenFlow
{
private class ScreenFlowEntry
{
public ScreenFlowEntry(string target, string previous, string step)
{
this.Target = target;
this.Previous = previous;
this.StepDefinition = step;
}
40
}
#region SingletonPattern
private static ScreenFlow instance;
private ScreenFlow()
{
LoadAppFlow();
}
}
}
41
previousEntry = GetEntryForTarget(previousEntry.Previous);
}
// reverse flow
steps.Reverse();
return steps;
}
return null;
}
All the automation scripts are up and running and if there is any flaw in any build the execution
of the scripts fails and would generate the report in Jenkins logs. With this we can track whether
the error which has occurred is due to a bug or script failure and can be fixed easily. The
execution of the scripts is done on a nightly basis by the Jenkins server.
Using SeeTest automation we were able to create an automation framework and have increased
the test coverage and speed by automating the test scripts. Test automation decreases the need
for manual testing and improves the coverage of test cases. The future work would be
maintaining and fixing the existing test scripts and automate any new test cases for the features
which come out in the later releases.
42