Tuesday, November 3, 2015

Wednesday, September 2, 2015

Xamarin Test Cloud: How to deploy your tests

Step 1: Go to https://testcloud.xamarin.com/

Step 2: Login and see your dashboard.

Step 3: Click "New Test Run" on the top right. Click which type of app you want to run tests for first.

Step 4: Select devices you want to run the test on.

Step 5: Test series is how your tests will be organized on your dashboard. You can order them by the number of test runs you plan to execute. So if you are only doing 5 or so devices, it is nice to label it small. Then you can do medium and large depending on your audience.

Step 6: Take this code, fill in the details for your application (apk file, assembly directory..).. the part I blue marked out is my API key and my email address (which you will have filled in for your test run). Then go into the Apple terminal and put it in.. submit it, and your tests will be added to Test Cloud! You can login and see your runs on their website.

You can put "--category "smoke"", or whatever attribute is above your tests to only run certain ones. If you look at my previous Xamarin post, I mentioned you can have
[Test]
[Category("smoke")]  // attribute for sending only certain tests
[Category("whatever2")]
public void TestNameHere()
{

}
And you add it to the Terminal code at the end like this..!
mono packages/Xamarin.UITest.1.0.0/tools/test-cloud.exe submit ../something.ipa APIKEYHERE --devices f37a5aa9 --series "small" --locale "en_US" --user hello@world.com --assembly-dir StuffHere/bin/Debug --category "smoke"
Or for Windows command prompt, something like this and change api key to the one given to you:
Users\ctenn\Desktop\testcloud\testcloud\AAA\packages\Xamarin.UITest.1.0.0\tools\test-cloud.exe submit CCApp\testcloud\com.AAA_TESTCLOUD_14_2.apk APIKEYHERE --devices d3939da0 --series "weekend" --locale "en_US" --app-name "AAA" --user email@email.com --assembly-dir CCApp\testcloud\AAA\AAA\bin\Debug
NOTE 1: You can also use Xamarin studio, go into your Test explorer, right click (or double tap whichever it is) the test you want.. and then click to submit it to Test Cloud. (I am just a stubborn web developer who lives off of Windows and Visual Studio).

NOTE 2: General expectations for how well applications will work on devices depends heavily on the device. Goal is to find out your audience and what types of phones they use to cover the vast majority of them. It is best to get the top say 10-20 devices working as close to 100% as you can. Then work to try and support bigger audience. When you get to the 40 newest devices point, you will start seeing massive fails in performance based on their capacity to deal with new applications and you can't really expect them to work perfectly. Chances are you will have difficulty supporting more than the top 80 realistically based on those phone's ability to perform and their memory.

Sunday, August 30, 2015

Xamarin and UI Automated Tests via Test Cloud

Xamarin is used to build, test, and monitor mobile applications. There is a Xamarin Studio IDE for development, and Test Cloud for testing your application across thousands of devices, and Xamarin Insights for monitoring. You do have to pay for these services and this is good for enterprise development for apps to be released on the app store that need to be as bug free as possible.

I will be focusing on UI Automated Tests and Test Cloud. The purpose of this post is to do a basic overview of what it can do and a little kickstart into how to use Xamarin for Automated UI Testing.

UI Automated Tests are tests that perform the manual taps / scrolls / typing / other interactions a person would normally have to do (QA). These are usually the more tedious interactions and many places would save a lot of time and stress by automating these tests. It allows for QA to do their more difficult specific work and remove the manual time consuming stuff. It also sniffs out differences in different platforms and a large scope of devices. The scope of these tests are basically anything you can do with direct interaction on the phone manually, doesn't involve only the back-end (use unit tests here), and can be performed while the mobile application is being run. You have the choice of using Calabash or C# as a language for development -- at this point when I have spoken with the Xamarin team, the functionalities of both languages are now about equal and you can choose one or the other (in the past you had good coverage with C#, but full coverage using Calabash). Calabash is basically the framework with all the methods and whatnot defined for you to use to perform the testing. Now the C# Xamarin.UITest assembly has the same methods open for use too.

Let's start with how to set up a suite for testing. Purchase Xamarin licenses. Startup a new empty C# solution. Add NuGet packages for Xamarin.UITest and nunit.framework. Now you can separate some folder structure into Global, Pages, and Tests. In this main directory, you will also want to make a new class and call it AppInitializer or something like this. HERE is the Xamarin documentation for starting an app. You will get your api key from Xamarin, and the other constants are your local builds. You can choose to use an emulator or a physical device for testing.
public static class AppInitializer
    {
        const string apiKey = "YOUR_API_KEY";
        const string apkPath = "YOUR LOCAL FILE";
        const string appFile = "YOUR LOCAL FILE";
        const string bundleId = "YOUR BUNDLE ID";

        public static IApp StartApp(Platform platform)
        {
            IApp app;
            if (platform == Platform.Android)
            {
                app = ConfigureApp
                    .Android
                    .ApiKey(apiKey)
                    .ApkFile(apkPath)
                    .StartApp();
            }
           // can add another if / else here for iOS

            return app;
        }
    }
You will need a base abstract class, let's just call it Setup.cs for now..this is how you will cause the app to hit the AppInitalizer.StartApp() function every time before you run a test. You will inherit from this base class on each new Test class.
public abstract class Setup
    {
        protected IApp app;
        protected Platform platform;

        protected AbstractSetup(Platform platform)
        {
            this.platform = platform;
        }

        [SetUp]
        public virtual void BeforeEachTest()
        {
            app = AppInitializer.StartApp(platform);
            if (platform == Platform.iOS)
            {
                // implement here
            }

            if (platform == Platform.Android)
            {
                // implement here
            }

            ResetApp();

            app.Screenshot("On Home Page");
        }

        public void ResetApp()
        {
            new GlobalPage(app, platform)
                .YourMethodNameHere();
        }
    }
So, back to the 3 sections:
  • Global: you can put methods you will use throughout the whole app, enums, a methods for swiping from left or right, things you will just need all the time no matter what page you are on and so you can avoid code duplication.
  • Pages: for each page in your app you plan to test, you should have a page for it with relevant properties and methods it will need. Let's say the mobile developers named their Main Logo iOS-main-logo and Android-main-logo.. the page is a good place to map these to YOUR testing property name, such as simply mainLogo. Now this makes ease for you to deal with any tapping on this mainLogo in your testing app and it is already mapped to both the Android and iOS versions. You can write basic functions like, TapLogoGoHome() into this page so no matter what you can call this function in the tests without needed to rewrite it over and over again.
  • Tests: Below is an example of a test. You have to have a [Test] attirbute. You can optionally have a "category" attribute which means that you can run a specific "playlist" of tests for example if you don't want to run them all every time. You will use this when sending it to Test Cloud and specify the cateogory of tests to run: in this example it can be smoke or secondCategory. You can add a test to as many lists as you like, just keeping adding them on a new line.
        [Test]
        [Category("smoke")]
        [Category("secondCategory")]
        public void SwipeOpenSideMenuAndGoHome()
        {
            string tapOrSwipe = "swipe";

            new GlobalPage(app, platform)
                .OpenSideMenu(tapOrSwipe);

            new SideMenuPage(app, platform)
                .NavigateToHome();

            new HomePage(app, platform);
        }
On GlobalPage, you will find the OpenSideMenu method, which does the actual .Tap() function.
    public class GlobalPage : BasePage
    {
        protected string menuButton;

        public GlobalPage(IApp app, Platform platform)
            : base(app, platform)
        {
            if (OnAndroid)
            {
                menuButton = "MenuButton";
            }
            if (OniOS)
            {
                menuButton = "y";
            }
        }

        public void OpenSideMenu(string TapOrSwipe = "tap")
        {
            app.Tap(menuButton);
            app.ScrollUp();
            app.WaitFor(isOpen, timeout: TimeSpan.FromSeconds(5));
        }
    }
Using the REPL is necessary to get the elements on the page needed to tap/scroll to get the test working. What you do is call app.Repl() inside of your code, you right click your test and put in Debug test and drop a breakpoint on your app.Repl line. After you hit it, step forward once.. and you will see a little pop up. Type "tree" with no quotation marks and this will give you a layout of everything on the page. SEE the Xamarin Repl tree explanation. Repl specifically spits out what is on the page you are on. You need the IDs (so ask your developers to ID everything in a logical fashion!) to find out what you need to tap and whatnot. You get it from the Repl, not from going through their codebase as this is much faster. If you find something you are not sure about, you can go into the Repl console box and type queries into like app.Flash(c=>c.Class("EditText")) and it will flash the item (blink so you can see it) and so you can tell if it is the right element or not. Sometimes there is no ID, now you have to grab the item some other way such as getting a Child(), Parent(), Descendant(), Sibling(), etc and the index of it (to see which number element it is). This can be good/bad.. it requires maintenance for if the index number or structure changes, but sometimes in a face paced environment without IDs there is no other choice. With app.Query(); you can get things like a count or the text from an element.
// for IDE Xamarin Studio or Visual Studio
stuffOnScreen = app.Query(x => x.Id(ListView).Child()).Count();
var currResult = app.Query(x => x.Id(ListView).Child(stuffOnScreen - 1).Descendant())[2].Text;


// for Repl() tree to find your element
app.Flash(x => x.Button())

// Everything on the page
app.Query()

// One element on the page by index
app.Query()[0]
app.Query()[36]

// total things on page
app.Query().Count()

// Certain matching element on page
app.query(x => x.Id("refresher") 

// Flashes and finds something on the page. 
app.Flash(x => x.Id("bill_iconImageButton"))

// Tap action on page
app.Tap("some_iconImageButton")

/// note that sometimes the Next button
/// is on the keyboard, 
/// so this...
app.Flash(x => x.Id("Next"))

// brings back nothing
// but! doing this in the Repl..
app.PressEnter()

// moves the page for you out of the keyboard and onto the next page. 
// Therefore.. add this to your test method 
app.PressEnter();

Last minute tips.. use the Object Browser on the Xamarin.UITest assembly a lot with the Xamarin doucmentation, it makes a lot more sense that way. The Xamarin developers and support are great and there for you if you need it! You can use emulators or physical devices. If you normally work on OSX or don't mind it, it is easier because you can run everything (Android emulators/iOS emulators or physical devices for both) in one place and use Xamarin Studio which is fully integrated. If you are like me.. you can try doing Windows and Visual Studio to run Android and develop everything there (you CANNOT emulate iOS here unless you have a nearby Apple computer and can use it as a building environment by connecting to it.. or..), then move the files over to the OSX/Xamarin Studio environment to run the iOS tests. Likely you will have to tweak the IDs of everything in iOS and debug the tests all over again as iOS behaves differently and things are likely labeled differently, too. Good luck!

Friday, July 31, 2015

LINQ cleanup

Just a little example of some code cleanup.. it's a-OK to break out a logic into something long to get it working and give it some thought. It's great to take your work and make it better using tools like LINQ to make it easier to read and less space. There are times it is not worth it to make it smaller if its harder to read, however. Also, it can be good to cleanup code you see in large projects to make things neater!

Here is one example with 2 pieces of code for looking up a username.. you can search it by first name, last name, or both. Likely for usability the future holds a sorting feature too!

Before lots of LINQ: After putting if/else cases into "or" inside .Where of LINQ:

Tuesday, July 28, 2015

Get; Set;

Taking a step backwards from my normal posts to some more basics.. I wanted to explain Get; Set; on properties to anyone new to software. I felt like some of the descriptions online were a little non-user friendly and wanted to help clarify it. This is done in C#, but the concepts are the same idea with other languages.

        public class Person
        {
            public string Name { get; set; }
            // Let's investigate this one
            public string Phone { get; set; }
        }

        // This is called an auto-implemented property. What does this really mean?
        public string Phone { get; set; }

        // This is the longhand / what really happens / the manual way to do this. 
        private string phone;
        public string Phone
        { 
            get { return phone; }
            set { phone = value; }
        }

        // Now what is THIS doing? Example time..
        // Make a Person1 of type Person. 
        Person Person1 = new Person();

        // Add a value to the property of Person. 
        Person1.Phone = "123-4567"; // **#1 see below

        // phone field
        private string phone; 
        
        // phone property
        public string Phone // **#1 hits this first, causing you to enter the braces..
        { 
            get { return phone; } // #3 returns little case phone, which has been assigned to value as property Phone
            set { phone = value; } // #2 sets the magical VALUE to little case phone
        }

        // So now if we ask for..
        // thingy will be "123-4567";
        var thingy = Person1.Phone;

        // where do we get value from????
        // "The word value references the value that client code is attempting to assign to the property." - MSDN
        // In other words.. Microsoft took care of it for you.
        // You try to access and set a property, it knows to assign that to "value"

        // With this version, you can make a new property based on other properties / customization
        // not there is only a get here. Its like a read only value
        public string PhoneString
        {
            get
            {
                string phoneNumString = "";
                
                // null safe it! 
                if (Person.Phone == null) return string.Empty;

                // if there's an area code, add it on! 
                if (!string.IsNullOrWhiteSpace(Person.Phone.AreaCode))
                    phoneNumString = "(" + Person.Phone.AreaCode + ") " + Person.Phone.PhoneNumber;
                else phoneNumString = Person.Phone.PhoneNumber; // if not, no biggie. 

                // if there's an extension, add it on too! 
                if (!string.IsNullOrWhiteSpace(Person.Phone.Extension)) phoneNumString += "ext." + Person.Phone.Extension;
                    
                return phoneNumString;
            }
        }

        // So, running with the example above... here's what you can and can't do.. 
        // NOPE. Can't set this. There is only a get. 
        Person1.Phonestring = "(813)123-4567 ext. 1000"; // This will fail and throw you an error. ANGRY RED SQUIGGLYS. 

        // But! You can do this. And then... 
        Person1.AreaCode = "813";
        Person1.Phone = "123-4567";
        Person1.Extension = "1000";

        //  result = "(813)123-4567 ext. 1000"
        var result = Person1.Phonestring;

Monday, July 27, 2015

Cool APIs


Little side applications are fun to make. Try thinking of add-ons to your favorite current apps/websites to make them even better and you can make your own project! Or these are great tools to incorporate to make something else new and cool. I love adding JS libraries and APIs from other people and places to make use of the awesome things people put out into the web to share.

Of course, Google. Google drive? Email self a document = upload to drive? Oh the million possible projects using Google..
https://developers.google.com/apis-explorer/#p/

Unfortunately, google does not have a free API for translating anymore (you have to pay..).. but Microsoft does! I used this in my AnkiTranslate project. Good for if you want to work with multiple languages or make study aids to learn another language.
https://www.microsoft.com/translator/api.aspx

Can I say wheel of lunch? Lunch picker? Thing to do picker?
https://www.yelp.com/developers/documentation/v2/overview

Practice stock market = $$$.. if you can get good at it.
https://code.google.com/p/yahoo-finance-managed/wiki/YahooFinanceAPIs

And more..
http://www.quora.com/What-are-some-cool-fun-APIs
http://www.computersciencezone.org/50-most-useful-apis-for-developers/
http://www.webdesignerdepot.com/2011/07/40-useful-apis-for-web-designers-and-developers/

LINQ Eager and Lazy Loading


Here's a little bit on using Linq and the ways to get data out via Eager / Lazy loading and LINQ methods vs operators. The explanations are in the code comments below.

using System.Data.Entity;
using System.Linq;
using EFFundamental;

namespace ConsoleApplication1
{
    class Program
    {
        // How to query against entity data model
        static void Main(string[] args)
        {
            LinqOperatorLazyLoading();
            LinqOperatorEagerLoading();
            LinqMethods();
            ProjectionQuery();
        }

        // using LINQ operator
        // Lazy loading = fetch only main data and have to make subsequent calls to get related data. 
        // Use when you know related data is not required at all or at the time of the call. 
        private static void LinqOperatorLazyLoading()
        {
            var context = new CHEntities();
            var query = from c in context.council_member 
                        where c.end_dtm != null
                        select c;
            
            var result = query.ToList();

           // note Lazy loading is by default, on.  If you want to change this..
           // context.ContextOptions.LazyLoadingEnabled = false;
        }

        // using LINQ operator
        // Eager loading = explicitly fetching all the data related in one call.
        // Good if all your stuff is not too large or you are unsure of what pieces of data you will need. 
        // If it is a large amount of data.. slower but more complete. 
        private static void LinqOperatorEagerLoading()
        {
            var context = new CHEntities();
            var query = from c in context.council_member.Include("address") // the .Include is what makes it Eager loading (these are the "extra" objects )
                                                        .Include(x => x.council_lku) // to use lambdas, make sure to add: using System.Data.Entity;
                        where c.end_dtm != null
                        select c;
            
            var result = query.FirstOrDefault();
        }

        // using LINQ methods .WHERE etc.. 
        private static void LinqMethods()
        {
            var context = new CHEntities();
            var result = context.Compliance_Notes.Where(x => x.last_updated_by == "ctenn").ToList();
        }

        private static void ProjectionQuery()
        {
            var context = new CHEntities();
            var query = from c in context.council_member.Include("address")
                        where c.end_dtm != null
                        // anonymous type and 2 of its properties. new object selecting only the properties you want. 
                        select new
                        {
                            c.branch, 
                            c.end_dtm
                        };
        }
    }
}