Some Trade Tools for Design, Development, QA and Dev Ops

Whimsical

A rapid wire-frame  and flow chart. It allows for collaboration.
If  you and your friends can work with up to 4 diagrams, then its free.

Sketch + Craft Plugin

Sketch allows you to design websites, iOS and Android interfaces easily.

Craft, a plugin made by InVision, provide some useful features to Sketch, such as:

  • Collaboration in real time
  • Allow to build prototypes based on design files
  • Allow for the synchronization of your design environment
  • Allows to load real data to your design
  • Its cloud enabled for sharing design assets
  • Allow for the clone of design elements.

Invision + Zeplin

Invision is another design platform, as well as the creators of the Craft plugin for Sketch.
It allows to design, document, and prototype websites, iOS, Android and more.
You need to use an email account in order to start the free version.

The Zeplin plugin provide accurate specs, assets and even code snippets made from the designs.
In our case, we are using the Zeplin plugin for Sketch.
It allows to export designs into Sketch, Adobe Photoshop CC, Figma and Sketch.
It provides extensions, some which you can even create yourself.
Create component libraries, do checklist to build every component, and tag people if needed.
If you are only working on one project at a time, you can do it by free by creating an account.

Framer

Note: Framer is for Mac OS only; however, they promise to bring a client version for Windows soon.

Framer allows you to design with code by using React. It provides a transitional and responding layout.

Adaptive layouts, design toolkit with logos and icons libraries, reusable and iterative components, video players, in-app icons and UI elements, and more powered by React.

Apiary

Apiary is an Oracle tool which allows you to design an API without requiring to write code. Then, you can share the designed API.
It allows for the use of Markdown, tests using mock servers, validation proxies and much more. Plus, it gives you code examples in different languages.
If you are a Command Line guy, there is a Apiary CLI Gem available.

Here is a Oracle session showing the best practices using this tool:

CircleCI

CircleCI is a continuous integration software. It will allow your teams to focus on working in incremental “stories”, each story is a code that will be merged incrementally into your shared repository software. The software can be setup to automate tests, deploys and much more. CircleCI is the equivalent of Jenkins or GitLab CI.

TestRail

TestRail is a test case management software which allows you to manage, design and run your test cases. It provide an insight of your testing progress; as well as to allow you to track issues and perform automation tests with your CI systems. It works with JIRA, Visual Studio,  Bugzilla, and up to 33 tools out there.

Here is a video example which shows how to add a test plan in TestRail:

FastLane

FastLane is a Continuous Delivery tool which allows you automate the building and release mobile apps. It is Open Source and design for the Android and iOS deployment.

With FastLane, there is no need to take screenshots, spend hours in code signing, figure out how to distribute beta builds, and such. This software is supposed to take care of all that.

Here is a video explanation made by Feliz Krause in MCE3 about deploying an iOS app in the App Store using FastLane:

Firebase Analytics

Firebase is a Google product. It provides all types of analysis data for web apps, mobile apps, Unity apps and more. It comes with multiple features such as authentication, database, cloud, hosting, analytics, remote config, performance monitoring and more. Below is a playlist of one of the features, Google Analytics for Firebase

One of the interesting things about Firebase is that includes Crashlytics. Crashlytics is a tool that allow you to keep track of the crashes in your apps and was made by Fabric.io. Google decided to ditch their own crash analytics tool and provide Crashlytics instead.

Its my understanding that Fabric was purchased by Google, so there is a whole promotion to move from Crashlytics to Firebase since Crashlytics seems to be included in Firebase. There is Crashlytics for iOS and Crashlytics for Android. By the time I am writing this post, I haven’t yet made the transition from Crashlytics to Firebase since I have to sit down and read all the policies, licenses and user agreements. I will try to keep you updated.

 

Share

SQL: Inner Join

Note: This is an experimental tutorial that I am building.

Welcome, my name is Alejandro and today we are reviewing SQL Inner Join.

When making a select query, using inner joins, we obtain a combination of rows from our tables. In other words, based on a join condition that matches obtain certain records coming from those tables. In our case, it is going to be between the table A and the table B.

For the table A, we have a list of clients and from the table B; we have a list of services. Both tables have fields known as columns and each column has records known as rows.

You should take particular attention to the field ID in both tables.This field is used to give a unique identifier to each of their records. Also, take attention to the ClientId field in the Services table. Yes. This field is a Foreign Key field, which holds IDs referring to the IDs in the Client table. We are going to match those IDs from both tables when doing the inner join. Below, I included an example of the result table that we wish to obtain.

Let us being by writing a basic select query. First, we are using the wildcard asterisk; this wildcard indicates that we wish to include all the fields, from all tables, used in our query. Second, we have a condition after the keyword ON. This condition will be used by the INNER JOIN to only pull records in which the ID of the client matches the ID in the ClientId fields from the Services table. The rest of the records should be ignored.

As you can see, we have the fields from the table clients, first; then, we have the fields from the services table.

At the Services table, I am showing an example of the record that will not be shown in the result table since there is not a match.

Now, this table does not resemble yet to the result table we wish to obtain. To display our table, as we want it, we need to indicate which fields from which tables we want to display. Plus, we must use the alias keyword AS, which allow us to show a different name for the fields in our result table.

Let’s see this working.

There are may online websites that will allow you to test your queries without requiring installing any software in your computer. One of my favorites is w3schools.com. This website has tutorials, references, quizzes and more.

Go to this link: W3Schools.com

On your right, you can see a list of tables that are at our disposition. We are going to duplicate what we did previously but using the tables Customers and Orders. From the table Customers, we only care about the fields CustomerId and CustomerName. From the table Orders, we only care for the fields OrderId and OrderDate. The following query will give us the results we wish to see:

Notices once again that we use the alias AS keyword to change the name for the column in our results.

Thank you for your time. I hope short instructional was useful for you. Since this is the first tutorial with video of a bunch I am planning to do. Your feedback is appreciated. Please have in consideration that this is a low budget production which I hope to improve in the long run as income and time allows it.

Share

JIRA: Useful Filters

Work Log Per Week

worklogAuthor = <Your Username> AND worklogDate >= startOfWeek() AND worklogDate <= endOfWeek()

Work Log Last Two Weeks

worklogAuthor = <Your Username> AND worklogDate >= startOfDay(-14d) AND worklogDate <= endOfDay()

All Tickets Where You Are the Assignee

assignee WAS currentUser()

All Defects Created Daily

issuetype in (Defect) AND “Group ID” IS NOT EMPTY AND “Environment” in (Production) AND createDate >= startOfDay(-1d)

Your Open Issues

assignee = currentUser() AND resolution = Unresolved order by updated DESC

Issued Viewed Currently

issuekey IN issueHistory() ORDER BY lastViewed DESC

Share

There are better options than using one array for names and another array for resources.

I encounter a piece of code which bugs me:

int[] images = {
		R.drawable.ic_image_1, R.drawable.ic_image_2, R.drawable.ic_image_3, R.drawable.ic_image_4, R.drawable.ic_image_5
		R.drawable.ic_image_6, R.drawable.ic_image_7, R.drawable.ic_image_8, R.drawable.ic_image_9, R.drawable.ic_image_10
};

String[] imagesNames = {
	"Image One", "Image Two", "Image Three", "Image Four", "Image Five", 
	"Image Six", "Image Seven", "Image Eight", "Image Nine", "Image Ten"
};

Later on, these two array are pass to all kind of method and constructors together for example:

    @Override
    public void onBindViewHolder(MasonryView holder, int position) {
        holder.textView.setText(imagesNames[position]);
        holder.imageView.setImageResource(images[position]);
    }

While this is correct, light on the memory, and use fewer CPU resources (less like of code run, smaller Big O), it welcomes all short of possible bugs, for example, lets say you add an image and forgot to add a name. You get mismatch arrays. Your code breaks. This issue is common if you are building these arrays dynamically; therefore, why not keeping the information together?

There are different ways to handle this

One way would be to create a class which holds these two items (image and image name). Then, you can create an array of objects.

private class Resource {
	public int image;
	public String name;
	Resource(String name, int image){
		this.image = image;
		this.name = name;
	}
}

Resource[] resources = {
	new Resources("Image One", R.drawable.ic_image_1),
	new Resources("Image Two", R.drawable.ic_image_2),
	new Resources("Image Three", R.drawable.ic_image_3),
	...
	new Resources("Image Ten", R.drawable.ic_image_10),
}

Then, you can iterate them:

    @Override
    public void onBindViewHolder(MasonryView holder, int position) {
        holder.textView.setText(resources[position].name);
	    holder.imageView.setImageResource(resources[position].image);
    }

Now, this is cleaner than before.

However, lets say you don’t wish to use a (public or private) class, then what to do? Well, you could use our old friend LinkedHashMap, which works like a HashMap; however, it keeps the order in which the elements were inserted into it.

LinkedHashMap = new LinkedHashMap<String, Integer>();
resources.put("One", R.drawable.ic_image_1);
resources.put("Two", R.drawable.ic_image_2);
...
resources.put("Ten", R.drawable.ic_image_10);

Now, here there is a problem. While you can iterate each of these items and get them based on the key (name), you cannot access them with an index. Do not despair! There is a solution around it by using the entrySet() method which is offer with the LinkedHashMap. The entrySet() method returns a set view of the mappings contained in the map. Lets see how it can help us:

resourcesIndexed = new ArrayList<Map.Entry<String, Integer>>(resources.entrySet());

    @Override
    public void onBindViewHolder(MasonryView holder, int position) {
        holder.textView.setText(resourcesIndexed.get(position).getKey());
        holder.imageView.setImageResource(resourcesIndexed.get(position).getValue());
    }

As you can see, without creating a container, such as a class, we can use an index to obtain the information and keep track of each pair.

 

Share