What Is Graphic Design: Our Complete Guide

Original Source: http://feedproxy.google.com/~r/Designrfix/~3/D6AUSMs5NvM/what-is-graphic-design

?Graphics are a visual way of communicating with someone. Billboard along highways try to sell us things or get us to stop at some location while images online work in much the same way. Somewhere at some point in time, a person designed everything we see that’s not part of nature. Quick Navigation A Deeper […]

The post What Is Graphic Design: Our Complete Guide appeared first on designrfix.com.

94% Off: Get the Fundamentals of Drawing Bundle for Only $39

Original Source: http://feedproxy.google.com/~r/Designrfix/~3/D-mb89qigLw/94-off-get-the-fundamentals-of-drawing-bundle-for-only-39

Most people believe that drawing is a natural talent. You’re either born with it or not. But the truth is that drawing is a skill that can be learned over time. If you’re considering taking a basic drawing class for the first time, be sure to check out the Fundamentals of Drawing Bundle. Fundamentals of […]

The post 94% Off: Get the Fundamentals of Drawing Bundle for Only $39 appeared first on designrfix.com.

Building Creative Websites Can Be Easy. Here’s How

Original Source: https://www.hongkiat.com/blog/building-creative-websites-can-be-easy/

Web designers, ready for some good news? We have some for you, and it involves designing creative websites. The ever-expanding global market is creating an equally expanding number of opportunities….

Visit hongkiat.com for full content.

Get Lifetime Access to the 2019 Interactive Coding Bootcamp for Only $39

Original Source: http://feedproxy.google.com/~r/Designrfix/~3/Ob0gQ5tZPME/get-lifetime-access-to-the-2019-interactive-coding-bootcamp-for-only-39

The demand for programmers is high and continues to increase. As the market for programmers grow, the buzz around coding bootcamps grow louder. If you want to get a quick dose of coding education, but you don’t have the luxury of time, then the 2019 Interactive Coding Bootcamp is for you. Here, you can learn […]

The post Get Lifetime Access to the 2019 Interactive Coding Bootcamp for Only $39 appeared first on designrfix.com.

92% Off: Enroll in the Complete Programming Language Bootcamp for Only $36

Original Source: http://feedproxy.google.com/~r/Designrfix/~3/1z8KfGxlahU/complete-programming-language-bootcamp

Learning is crucial for success. If you want to take your career to the next level, you need to invest in yourself. After all, an investment in knowledge pays the best interest. As such, we encourage you to enroll in short courses, attend some seminars or workshops. If you want to explore different programming languages […]

The post 92% Off: Enroll in the Complete Programming Language Bootcamp for Only $36 appeared first on designrfix.com.

20 Freshest Web Designs, August 2019

Original Source: https://www.webdesignerdepot.com/2019/08/20-freshest-web-designs-august-2019/

This month we leap back to the culture of America circa 1969, dive into the oceans with whales, discover multiple approaches to pitching a design agency, get invited to festivals, and shop online the right way. Enjoy!

Kilotype

Kilotype’s awesome new site shows off its variable fonts with a clever mouse-track — move your cursor around the screen vertically and horizontally to see the full range of each family’s weight and italic.

Once Upon a Time in Hollywood

The latest film from Tarantino is steeped in the culture of 1969, from the moon landing to Woodstock. This amazing promo-site does an incredible job of transporting you to a different era.

Wade and Leta

Wade and Leta are a partnership of talented art directors, whose offbeat sense of the absurd leads to some truly original and inspiring work. The homepage videos range from hilarious to bizarre.

Morenita

If there’s one place I’d like to be right now, it’s floating around the coast of Menorca on beautiful traditional fishing boat, and that’s all thanks to this inspiring site for Balearic boat hire.

The Believer Magazine

The site for The Believer Magazine is charmingly counter-culture, with deceptively sophisticated typography and New Yorker-quality illustration. Exactly what you’d expect from a modern culture publication.

Cher Ami

Cher Ami’s site features plenty of engaging work, but it’s the little details that make this site special, like the way the menu flies out not-quite-square, and the hyperspace-style transitions.

Good Day

Good Day sells CBD-infused beverages from a tastefully minimal site. At roughly $6/drink, it’s not cheap, and this sophisticated site is ideal for positioning the company in the luxury consumables market.

Dice

Dice is a German music and arts festival. Its site features some incredible, generated organic shapes, with animated gradients to match, and the seamless eternal scroll is a delight.

Flatiron Collective

The Flatiron Collective site opens with animated illustration. It’s an eye-catching pitch for business, far into left-field from the usual agency promotional site, and doesn’t even showcase previous work.

Save Whales

Whales are among the most intelligent, graceful, and magical creatures in the world. This inspiring site features extraordinary photography and facts about the magnificent creatures.

InDnegev

InDnegev is an Israeli music festival with a psychedelic animated site. The site features bold color choices, subtle animation, and two people riding a giant fox made out of stars, because why not.

Gucci Marmont

One of the big trends in online shopping is 3D, and Gucci’s Marmont collection jumps on this trend with a 17th-century inspired art exhibition featuring its latest purses. Scroll to browse.

Oust

Oust is a leading creative agency with tons of amazing work. Instead of pressing its portfolio, Oust’s site shows off the energy and ambition of the company’s professional culture.

Gantri

Gantri designs better lights, and its site is a glorious collection of careful ecommerce best practices and stellar product photography. This is exactly how you should sell products online.

eyehealth1st

Look Deeper is an eye health campaign from Australia that wants to educate you about the dangers your eyes face, with an impactful infographic style site highlighting the various threats to your eyesight.

Ada Sokół

Ada Sokół’s portfolio is designed to focus entirely on her unique brand of futuristic, 3D artwork. Alongside commercial work you’ll also find some exceptional personal work.

Stuuudio

Embracing the www-ness of using three letters, where one would be too real-world, is Stuuudio, a design agency with a nice line in blobby-animated transitions. It’s a good take on the classic agency site.

Ocean Vagabond

Ocean Vagabond is a watersports company in Morocco. Its homepage features some small-scale video, but navigate to one of the location pages for inspiring video and typography interaction.

Festival

Festival is a vibrant and engaging one-pager for the Camberwell College of Art undergraduate degree show. With light-hearted typography and interactive confetti, it’s a great online invitation.

Neutral Works

Neutral Works is another design agency with a penchant for interesting, liquid-style transitions. Based in Japan, it’s fascinating to see the different approach to familiar products in a foreign culture.

Source

p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

15 wp-config Snippets to Configure WordPress Site

Original Source: https://www.hongkiat.com/blog/wpconfig-snippets-configure-wordpress/

WordPress admin makes it easy to manage configurations without touching a line of code. These basic configuration settings are then stored in the wp-options table inside the database. But, WordPress…

Visit hongkiat.com for full content.

Bringing A Better Design Process To Your Organization

Original Source: https://www.smashingmagazine.com/2019/08/better-design-process-organization/

Bringing A Better Design Process To Your Organization

Bringing A Better Design Process To Your Organization

Eric Olive

2019-08-21T13:30:59+02:00
2019-08-22T17:06:41+00:00

As user experience (UX) designers and researchers, the most common complaint we hear from users is:

“Why don’t they think about what I need?”

In fact, many organizations have teams dedicated to delivering what users and customers need. More and more software developers are eager to work with UX designers in order to code interfaces that customers will use and understand. The problem is that complex software projects can easily become bogged down in competing priorities and confusion about what to do next.

The result is poor design that impedes productivity. For example, efficiency in healthcare is hampered by electronic medical records (EMRs). Complaints about these software systems are legion. Dr. Steven Ugent, a Boston-based dermatologist and Yale Medical School alumnus, is no exception.

Since 2010, Dr. Ugent has used two EMR systems: Before 2010, he finished work promptly at 5:15 every day. Since he and his colleagues started using EMRs, he typically works an extra half hour to 1.5 hours in the evening. “I don’t know any doctor who is happy with their medical records system. The crazy thing is that I was much more efficient when I was using pen and paper.”

man holding pen on paper

The EMR systems are clunky, inflexible, and hard to customize. Ugent, for instance, cannot embed photos directly into his chart notes. Instead, he must open the folder with the photo of the mole and then open a different folder to see the text. This setup is particularly cumbersome for dermatologists who rely heavily on photos when treating patients.

Ugent succinctly summarizes the problem with EMRs:

“The people who design it [the EMR system] don’t understand my workflow. If they did, they would design a different system.”

Doctors are not alone in their frustration with clunky software. Consumers and professionals around the world make similar complaints:

“Why can’t I find what I need?”

“Why do they make it so hard?”

“Why do I have to create a login when I simply want to buy this product. I’m giving them money. Isn’t that enough?”

A major contributor to clunky software is flawed design processes. In this article, we’ll outline four design process problems and explain how to address them.

Complexity
Next-Release Syndrome
Insufficient Time For Design Iterations
Surrendering Control To Outside Vendors

1. Complexity

Scale, multiple stakeholders, and the need for sophisticated code are among the many factors contributing to the complexity of large software projects.

Sometimes overlooked, however, are complex laws and regulations. For example, insurance is heavily regulated at the state level, adding a layer of complexity for insurance companies operating in multiple states. Banks and credit unions are subject to regulation while utilities must comply with state and federal environmental laws.

Healthcare products and software subject to FDA regulations offer an even greater challenge. The problem isn’t that the regulations are unreasonable. Safety is paramount. The issues are time, budget, and the planning necessary to meet FDA requirements.

As Jeff Horvath, Ph.D., a UX consultant with extensive experience in healthcare, explains: “These requirements add a couple of orders of magnitude to the rigor for writing test protocols, test setup, data gathering, analysis, quality controls, and getting approval to conduct the research in the first place.” For example, a single round of usability testing jumps from six weeks (a reasonable time frame for a standard usability test) to six months. And that’s with a single round of usability testing. Often, two or more rounds of testing are necessary.

This level of rigor is a wakeup call for companies new to working with the FDA. More than once, Horvath has faced tough conversations with clients who were unprepared for the extended timelines and additional budget necessary to meet FDA requirements. It’s hard, but necessary. “It pays to be thorough,” says Horvath. In 2018 the FDA approved a mere 11% of pre-market submissions.

The demands on researchers, designers, and developers are higher for healthcare software requiring FDA compliance than for traditional software products. For example:

A UX researcher can only conduct one or two usability test sessions per day as opposed to the more common five to six sessions per day for standard software.
UX designers must remain hyper-attentive to every aspect of the user’s interaction with software. Even one confusing interaction could cause a clinician to make an error that could jeopardize a patient’s health. For the same reason, UI designers must draw interfaces that remain faithful to every interaction.
A longer time frame for design and usability testing means that the developer’s coding efforts must be planned carefully. Skilled and well-intentioned developers are often eager to modify the code as soon as new information becomes available. While this approach can work in organizations well practiced in rapid iteration, it carries risk when designing and coding complex systems.

Failure to manage complexity can have fatal consequences as happened when Danielle McCray was admitted to Tallahassee Memorial Hospital as she was about to give birth. To ease her discomfort, healthcare workers connected her to a patient-controlled analgesia machine, a programmable infusion pump.

Eight hours later McCray was pronounced dead from a morphine overdose. A major factor in this tragedy was the flawed design of the infusion pump used to administer medication. The pump required 27 programming steps. Failure to address such complexity by designing a more intuitive user interface contributed to unnecessary death.

Solution

The solution is to acknowledge and address complexity This point sounds logical. Yet, as explained above, complicated FDA regulations often surprise company leaders. Denial doesn’t work. Failing to plan means your organization will likely fall into the 89% of pre-market submissions the FDA rejected in 2018.

When conducting usability tests, user experience researchers must take three steps to manage the complexity associated with FDA regulations:

The moderator (the person who runs the usability test) must be hyper-attentive. For example, if an MRI scan requires a technician to follow a strict sequence of steps while using the associated software, the moderator must observe carefully to determine if the participant follows the instructions to the letter. If not, the task is rated as a failure meaning that both the interface design and associated documentation will require modification;
The moderator must also track close calls. For example, a participant might initially perform the steps out of order, discover the mistake, and recover by following the proper sequence. The FDA considers this a near miss, and the moderator must report it as such;
The moderator must also assess the participant’s knowledge. Does she believe that she has followed the proper sequence? Is this belief accurate?

2. Next-Release Syndrome

One factor in the failure to acknowledge complexity is a fix-it-later mindset we call next-release syndrome. Software bugs are not a problem because “we’ll fix that in the next release.” The emphasis on speed over quality and safety makes it all too easy to postpone solving the hard problems.

Anyone involved in product design and development must tackle next-release syndrome. Two examples make the point:

We discovered serious design flaws with a client’s healthcare tracking software. The company chose to release the software without addressing these problems. Not surprisingly, customers were unhappy.
We conducted usability tests for a large credit union based in the U.S. The participants were seasoned financial advisers. Testing revealed serious design flaws including confusing status icons, buttons with an unclear purpose, and a nearly hidden link that prevented participants from displaying important data. Remember, if the user doesn’t see it, it’s not there. When we reported the findings, the response was: “We’ll fix that in the next release.” As expected, the web application was not well received. Responses from users included: “Why did you ask us to review the app if you had no intention of making changes?”

Solution: Reject The Fix-It-Next-Time Mentality

The solution is to address serious design problems now. Sounds straightforward. But, how do you convince decision-makers to change the entrenched “fix-it-later” mindset?

The key is to shift the conversation about achievement away from product delivery toward the value created. For example, teams that take the time to revise a design based on user research are likely to see better customer reactions and, over time, increased customer loyalty.

Strengthen the case by using quantitative data to show decision-makers the direct connection between user research and increased revenue and a positive customer experience.

Use data to connect research and design improvements to specific business goals

Use data to connect research and design improvements to specific business goals (Large preview)

Re-defining value is, in effect, a process improvement because it establishes a new set of priorities that better serve customers and your company’s long-term interests. As McKinsey reports in The Business Value of Design: “Top-quartile companies embrace the full user experience; they break down internal barriers among physical, digital, and service design.”

3. Insufficient Time For Design Iterations

Related to the next-release syndrome is insufficient time to iterate the design based on research findings or changing business requirements. “We don’t have time for that,” is the common refrain from developers and product owners. Designers working in Agile environments are frequently pressured to avoid “holding up” the development team.

Development speeds along, and the software is released. We’ve all seen the results from confusing phone apps, to clunky medical records software, to the cumbersome user interface for financial advisers referenced above.

Solution: Design Spikes

One solution comes from the coding world. In his article “Fitting Big-Picture UX Into Agile Development”, Damon Dimmick offers the idea of design spikes, “bubbles of time that allow designers to focus on complex UX issues.” They fit into the Scrum framework by temporarily taking the place of a regular sprint.

Design iteration

Design iteration (Large preview)

Design spikes offer several advantages:

They allow UX teams to focus on holistic issues and avoid getting bogged down in granular design issues that are sometimes emphasized within a single sprint;
They offer the opportunity to explore complex UX questions from a high level. If needed, the UX design team can also engage in design-centric thinking at any point in order to solve larger UX challenges;
By adopting design spikes, UX teams can leverage the same flexibility that development teams use in the agile process and devote the time needed to focus on design issues that don’t always fit well into a standard scrum sprint;
Development unlikely to be affected by design decisions can proceed.

Naturally, design iterations often affect certain parts of the code for a site, app, or software product. For this reason, during design spikes any code that will likely be affected by the design spike cannot move forward. But, as Dimmick clearly states, this “delay” will likely save time by avoiding re-work. It simply does not make sense to write code now and then re-write it a few weeks later after the team has agreed on a revised design. In short, postponing some coding actually saves time and budget.

4. Relying Too Heavily On Vendors

Addressing complexity, resisting next-release syndrome, and allowing time for iteration are essential to an effective design process. For many firms, another consideration is their relationship with software vendors. These vendors play an important, even critical, role in development. Yet, granting them too much leverage makes it difficult to control your own product.

Outsourcing to software vendors

Outsourcing to software vendors (Large preview)

Certainly, we should treat colleagues and vendors with respect and make reasonable requests. That doesn’t mean, however, that it’s necessary to surrender all leverage as happened during my tenure at a large finance firm.

While working at this firm as a UX designer, I frequently encountered this dynamic:

Manager: “Hey, Eric can you evaluate this claims software that we’re planning to buy? We just want to make sure it works as intended.”

Me: “Sure, I’ll send you my preliminary findings by the end of the week.”

Manager: “Great”

The following week:

Manager: “Thanks for the review. I see that you found three serious issues: Hard to find the number for an existing claim, screens with too much text that are hard to read, and the difficulty of returning to a previous screen when processing a new claim. That is concerning. Do you think those issues will hinder productivity?”

Me: “Yes, I think these issues will increase stress and processing time in the Claims Center. I’m quite concerned because my previous work with Janet’s team demonstrated that the Claims Center reps are already highly stressed.”

Manager: “Really good to know. I just sent the check. I’ll ask the vendor to fix the problems before they ship.”

Me (screaming inside): “Noooooooooooooo!”

This well-intentioned manager did precisely the wrong thing. He asked for changes after sending the check. No surprise that the vendor never made the requested changes. Why would they? They had their money.

Not only did this scenario play out repeatedly at that company, but I’ve witnessed it throughout my UX career.

Solution

The solution is clear. If the vendor product does not meet customer and business needs, and the changes you request are within scope, don’t pay until the vendor makes the changes. It really is that simple.

Conclusion

In this piece, we’ve identified four common barriers to quality design and corresponding solutions:

Complex regulations and standards
The solution is to acknowledge and address complexity by devising realistic timelines and sufficient budget for research and iterative design.
Shipping software with bugs with a promise to fix them later
The solution is to avoid next-release syndrome and address serious problems now. Persuade decision-makers by re-defining the meaning of value within your organization.
Insufficient time for design iterations
The solution is to include design spikes in the agile development process. These bubbles of time temporarily take the place of a sprint and allow designers to focus on complex UX issues.
Relying too heavily on vendors
The solution is to retain leverage by withholding final payment until the vendor makes requested changes as long as these changes are within the original project scope.

The fourth solution is straightforward. While the first three are not easy, they are concrete because they can be applied directly to existing design processes. Their implementation does not require a massive reorganization or millions of dollars. It simply requires commitment to delivering a better experience.

Smashing Editorial
(ah, il)

Testing Made Easier Via Framework Minimalism And Software Architecture

Original Source: https://www.smashingmagazine.com/2019/08/testing-framework-minimalism-software-architecture/

Testing Made Easier Via Framework Minimalism And Software Architecture

Testing Made Easier Via Framework Minimalism And Software Architecture

Ryan Kay

2019-08-22T13:00:59+02:00
2019-08-22T16:35:57+00:00

Like many other Android developers, my initial foray into testing on the platform lead me to be immediately confronted with a demoralizing degree of jargon. Further, what few examples I came across at the time (circa 2015) did not present practical use cases which may have inclined me to think that the cost to benefit ratio of learning a tool like Espresso in order to verify that a TextView.setText(…) was working properly, was a reasonable investment.

To make matters even worse, I did not have a working understanding of software architecture in theory or practice, which meant that even if I bothered to learn these frameworks, I would have been writing tests for monolithic applications comprised of a few god classes, written in spaghetti code. The punchline is that building, testing, and maintaining such applications is an exercise in self-sabotage quite regardless of your framework expertise; yet this realization only becomes clear after one has built a modular, loosely-coupled, and highly-cohesive application.

From here we arrive at one of the main points of discussion in this article, which I will summarize in plain language here: Among the primary benefits of applying the golden principles of software architecture (do not worry, I will discuss them with simple examples and language), is that your code can become easier to test. There are other benefits to applying such principles, but the relationship between software architecture and testing is the focus of this article.

However, for the sake of those who wish to understand why and how we test our code, we will first explore the concept of testing by analogy; without requiring you to memorize any jargon. Before getting deeper into the primary topic, we will also look at the question of why so many testing frameworks exist, for in examining this we may begin to see their benefits, limitations, and perhaps even an alternative solution.

Testing: Why And How

This section will not be new information for any seasoned tester, but perhaps you may enjoy this analogy nonetheless. Of course I am a software engineer, not a rocket engineer, but for a moment I will borrow an analogy which relates to designing and building objects both in physical space, and in the memory space of a computer. It turns out that while the medium changes, the process is in principle quite the same.

Suppose for a moment that we are rocket engineers, and our job is to build the first stage* rocket booster of a space shuttle. Suppose as well, that we have come up with a serviceable design for the first stage to begin building and testing in various conditions.

“First stage” refers to boosters which are fired when the rocket is first launched

Before we get to the process, I would like to point out why I prefer this analogy: You should not have any difficulty answering the question of why we are bothering to test our design before putting it in situations where human lives are at stake. While I will not try to convince you that testing your applications before launch could save lives (although it is possible depending on the nature of the application), it could save ratings, reviews, and your job. In the broadest sense, testing is the way in which we make sure that single parts, several components, and whole systems work before we employ them in situations where it is critically important for them to not fail.

Returning to the how aspect of this analogy, I will introduce the process by which engineers go about testing a particular design: redundancy. Redundancy is simple in principle: Build copies of the component to be tested to the same design specification as what you wish to use at launch time. Test these copies in an isolated environment which strictly controls for preconditions and variables. While this does not guarantee that the rocket booster will work properly when integrated in the whole shuttle, one can be certain that if it does not work in a controlled environment, it will be very unlikely to work at all.

Suppose that of the hundreds, or perhaps thousands of variables which the copies of the rocket design have been tested against, it comes down to ambient temperatures in which the rocket booster will be test fired. Upon testing at 35° Celsius, we see that everything functions without error. Again, the rocket is tested at roughly room temperature without failure. The final test will be at the lowest recorded temperature for the launch site, at -5° Celcius. During this final test, the rocket fires, but after a short period, the rocket flares up and shortly thereafter explodes violently; but fortunately in a controlled and safe environment.

At this point, we know that changes in temperature appear to be at least involved in the failed test, which leads us to consider what parts of the rocket booster may be adversely effected by cold temperatures. Over time, it is discovered that one key component, a rubber O-ring which serves to staunch the flow of fuel from one compartment to another, becomes rigid and ineffectual when exposed to temperatures approaching or below freezing.

It is possible that you have noticed that his analogy is loosely based on the tragic events of the Challenger space shuttle disaster. For those unfamiliar, the sad truth (insofar as investigations concluded) is that there were plenty of failed tests and warnings from the engineers, and yet administrative and political concerns spurred the launch to proceed regardless. In any case, whether or not you have memorized the term redundancy, my hope is that you have grasped the fundamental process for testing parts of any kind of system.

Concerning Software

Whereas the prior analogy explained the fundamental process for testing rockets (while taking plenty of liberty with the finer details), I will now summarize in a manner which is likely more relevant to you and I. While it is possible to test software by only launching it to devices once it is in any sort of deployable state, I suppose instead that we can apply the principle of redundancy to the individual parts of the application first.

This means that we create copies of the smaller parts of the whole application (commonly referred to as Units of software), set up an isolated test environment, and see how they behave based on whatever variables, arguments, events, and responses which may occur at runtime. Testing is truly as simple as that in theory, but the key to even getting to this process lies in building applications which are feasibly testable. This comes down to two concerns which we will look at in the next two sections. The first concern has to do with the test environment, and the second concern has to do with the way in which we structure applications.

Why Do We Need Frameworks?

In order to test a piece of software (henceforth referred to as a Unit, although this definition is deliberately an over-simplification), it is necessary to have some kind of testing environment which allows you to interact with your software at runtime. For those building applications to be executed purely on a JVM (Java Virtual Machine) environment, all that is required to write tests is a JRE (Java Runtime Environment). Take for example this very simple Calculator class:

class Calculator {
private int add(int a, int b){
return a + b;
}

private int subtract(int a, int b){
return a – b;
}
}

In absence of any frameworks, as long as we have a test class which contains a mainfunction to actually execute our code, we can test it. As you may recall, the main function denotes the starting point of execution for a simple Java program. As for what we are testing for, we simply feed some test data into the Calculator’s functions and verify that it is performing basic arithmetic properly:

public class Main {

public static void main(String[] args){
//create a copy of the Unit to be tested
Calculator calc = new Calculator();
//create test conditions to verify behaviour
int addTest = calc.add(2, 2);
int subtractTest = calc.subtract(2, 2);

//verify behaviour by assertion
if (addTest == 4) System.out.println(“addTest has passed.”);
else System.out.println(“addTest has failed.”);

if (subtractTest == 0) System.out.println(“subtractTest has passed.”);
else System.out.println(“subtractTest has failed.”);
}
}

Testing an Android application is of course, a completely different procedure. Although there is a main function buried deep within the source of the ZygoteInit.java file (the finer details of which are not important here), which is invoked prior to an Android application being launched on the JVM, even a junior Android developer ought to know that the system itself is responsible for calling this function; not the developer. Instead, the entry points for Android applications happen to be the Application class, and any Activity classes which the system can be pointed to via the AndroidManifest.xml file.

All of this is just a lead up to the fact that testing Units in an Android application presents a greater level of complexity, strictly because our testing environment must now account for the Android platform.

Taming The Problem Of Tight Coupling

Tight coupling is a term which describes a function, class, or application module which is dependent on particular platforms, frameworks, languages, and libraries. It is a relative term, meaning that our Calculator.java example is tightly coupled to the Java programming language and standard library, but that is the extent of its coupling. Along the same lines, the problem of testing classes which are tightly coupled to the Android platform, is that you must find a way to work with or around the platform.

For classes tightly coupled to the Android platform, you have two options. The first, is to simply deploy your classes to an Android device (physical or virtual). While I do suggest that you test deploy your application code before shipping it to production, this is a highly inefficient approach during the early and middle stages of the development process with respect to time.

A Unit, however technical a definition you prefer, is generally thought of as a single function in a class (although some expand the definition to include subsequent helper functions which are called internally by the initial single function call). Either way, Units are meant to be small; building, compiling, and deploying an entire application to test a single Unit is to miss the point of testing in isolation entirely.

Another solution to the problem of tight coupling, is to use testing frameworks to interact with, or mock (simulate) platform dependencies. Frameworks such as Espresso and Robolectric give developers far more effective means for testing Units than the previous approach; the former being useful for tests run on a device (known as “instrumented tests” because apparently calling them device tests was not ambiguous enough) and the latter being capable of mocking the Android framework locally on a JVM.

Before I proceed to railing against such frameworks instead of the alternative I will discuss shortly, I want to be clear that I do not mean to imply that you should never use these options. The process which a developer uses to build and test their applications should be born of a combination of personal preference and an eye for efficiency.

For those who are not fond of building modular and loosely coupled applications, you will have no choice but to become familiar with these frameworks if you wish to have an adequate level of test coverage. Many wonderful applications have been built this way, and I am not infrequently accused of making my applications too modular and abstract. Whether you take my approach or decide to lean heavily on frameworks, I salute you for putting in the time and effort to test your applications.

Keep Your Frameworks At Arms Length

For the final preamble to the core lesson of this article, it is worth discussing why you might want to have an attitude of minimalism when it comes to using frameworks (and this applies to more than just testing frameworks). The subtitle above is a paraphrase from the magnanimous teacher of software best practices: Robert “Uncle Bob” C. Martin. Of the many gems he has given me since I first studied his works, this one took several years of direct experience to grasp.

Insofar As I understand what this statement is about, the cost of using frameworks is in the time investment required to learn and maintain them. Some of them change quite frequently and some of them do not change frequently enough. Functions become deprecated, frameworks cease to be maintained, and every 6-24 months a new framework arrives to supplant the last. Therefore, if you can find a solution which can be implemented as a platform or language feature (which tend to last much longer), it will tend to be more resistant to changes of the various types mentioned above.

On a more technical note, frameworks such as Espresso and to a lesser degree Robolectric, can never run as efficiently as simple JUnit tests, or even the framework free test from earlier on. While JUnit is indeed a framework, it is tightly coupled to the JVM, which tends to change at a much slower rate than the Android platform proper. Fewer frameworks almost invariably means code which is more efficient in terms of the time it takes to execute and write one or more tests.

From this, you can probably gather that we will now be discussing an approach which will leverage some techniques which allows us to keep the Android platform at arms length; all the while allowing us plenty of code coverage, test efficiency, and the opportunity to still use a framework here or there when the need arises.

The Art Of Architecture

To use a silly analogy, one might think of frameworks and platforms as being like overbearing colleagues who will take over your development process unless you set appropriate boundaries with them. The golden principles of software architecture can give you the general concepts and specific techniques necessary to both create and enforce these boundaries. As we will see in a moment, if you have ever wondered what the benefits of applying software architecture principles in your code truly are, some directly, and many indirectly make your code easier to test.

Separation Of Concerns

Separation Of Concerns is by my estimation the most universally applicable and useful concept in software architecture as a whole (without meaning to say that others should be neglected). Separation of concerns (SOC) can be applied, or completely ignored, across every perspective of software development I am aware of. To briefly summarize the concept, we will look at SOC when applied to classes, but be aware that SOC can be applied to functions through extensive usage of helper functions, and it can be extrapolated to entire modules of an application (“modules” used in the context of Android/Gradle).

If you have spent much time at all researching software architectural patterns for GUI applications, you will likely have come across at least one of: Model-View-Controller (MVC), Model-View-Presenter (MVP), or Model-View-ViewModel (MVVM). Having built applications in every style, I will say upfront that I do not consider any of them to be the single best option for all projects (or even features within a single project). Ironically, the pattern which the Android team presented some years ago as their recommended approach, MVVM, appears to be the least testable in absence of Android specific testing frameworks (assuming you wish to use the Android platform’s ViewModel classes, which I am admittedly a fan of).

In any case, the specifics of these patterns are less important than their generalities. All of these patterns are just different flavours of SOC which emphasize a fundamental separation of three kinds of code which I refer to as: Data, User Interface, Logic.

So, how exactly does separating Data, User Interface, and Logic help you to test your applications? The answer is that by pulling logic out of classes which must deal with platform/framework dependencies into classes which possess little or no platform/framework dependencies, testing becomes easy and framework minimal. To be clear, I am generally talking about classes which must render the user interface, store data in a SQL table, or connect to a remote server. To demonstrate how this works, let us look at a simplified three layer architecture of a hypothetical Android application.

The first class will manage our user interface. To keep things simple, I have used an Activity for this purpose, but I typically opt for Fragments instead as user interface classes. In either case, both classes present similar tight coupling to the Android platform:

public class CalculatorUserInterface extends Activity implements CalculatorContract.IUserInterface {

private TextView display;
private CalculatorContract.IControlLogic controlLogic;
private final String INVALID_MESSAGE = “Invalid Expression.”;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

controlLogic = new DependencyProvider().provideControlLogic(this);

display = findViewById(R.id.textViewDisplay);
Button evaluate = findViewById(R.id.buttonEvaluate);
evaluate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
controlLogic.handleInput(‘=’);
}
});
//..bindings for the rest of the calculator buttons
}

@Override
public void updateDisplay(String displayText) {
display.setText(displayText);
}

@Override
public String getDisplay() {
return display.getText().toString();
}

@Override
public void showError() {
Toast.makeText(this, INVALID_MESSAGE, Toast.LENGTH_LONG).show();
}
}

As you can see, the Activity has two jobs: First, since it is the entry point of a given feature of an Android application, it acts as a sort of container for the other components of the feature. In simple terms, a container can be thought of as a sort of root class which the other components are ultimately tethered to via references (or private member fields in this case). It also inflates, binds references, and adds listeners to the XML layout (the user interface).

Testing Control Logic

Rather than having the Activity possess a reference to a concrete class in the back end, we have it talk to an interface of type CalculatorContract.IControlLogic. We will discuss why this is an interface in the next section. For now, just understand that whatever is on the other side of that interface is supposed to be something like a Presenter or Controller. Since this class will be controlling interactions between the front-end Activity and the back-end Calculator, I have chosen to call it CalculatorControlLogic:

public class CalculatorControlLogic implements CalculatorContract.IControlLogic {

private CalculatorContract.IUserInterface ui;
private CalculatorContract.IComputationLogic comp;

public CalculatorControlLogic(CalculatorContract.IUserInterface ui, CalculatorContract.IComputationLogic comp) {
this.ui = ui;
this.comp = comp;
}

@Override
public void handleInput(char inputChar) {
switch (inputChar){
case ‘=’:
evaluateExpression();
break;
//…handle other input events
}
}
private void evaluateExpression() {
Optional result = comp.computeResult(ui.getDisplay());

if (result.isPresent()) ui.updateDisplay(result.get());
else ui.showError();
}
}

There are many subtle things about the way in which this class is designed that make it easier to test. Firstly, all of its references are either from the Java standard library, or interfaces which are defined within the application. This means that testing this class without any frameworks is an absolute breeze, and it could be done locally on a JVM. Another small but useful tip is that all of the different interactions of this class can be called via a single generic handleInput(…) function. This provides a single entry point to test every behaviour of this class.

Also note that in the evaluateExpression() function, I am returning a class of type Optional<String> from the back end. Normally I would use what functional programmers call an Either Monad, or as I prefer to call it, a Result Wrapper. Whatever stupid name you use, it is an object which is capable of representing multiple different states through a single function call. Optional is a simpler construct which can represent either a null, or some value of the supplied generic type. In any case, since the back end might be given an invalid expression, we want to give the ControlLogicclass some means of determining the result of the backend operation; accounting for both success and failure. In this case, null will represent a failure.

Below is an example test class which has been written using JUnit, and a class which in testing jargon is called a Fake:

public class CalculatorControlLogicTest {

@Test
public void validExpressionTest() {

CalculatorContract.IComputationLogic comp = new FakeComputationLogic();
CalculatorContract.IUserInterface ui = new FakeUserInterface();
CalculatorControlLogic controller = new CalculatorControlLogic(ui, comp);

controller.handleInput(‘=’);

assertTrue(((FakeUserInterface) ui).displayUpdateCalled);
assertTrue(((FakeUserInterface) ui).displayValueFinal.equals(“10.0”));
assertTrue(((FakeComputationLogic) comp).computeResultCalled);

}

@Test
public void invalidExpressionTest() {

CalculatorContract.IComputationLogic comp = new FakeComputationLogic();
((FakeComputationLogic) comp).returnEmpty = true;
CalculatorContract.IUserInterface ui = new FakeUserInterface();
((FakeUserInterface) ui).displayValueInitial = “+7+7”;
CalculatorControlLogic controller = new CalculatorControlLogic(ui, comp);

controller.handleInput(‘=’);

assertTrue(((FakeUserInterface) ui).showErrorCalled);
assertTrue(((FakeComputationLogic) comp).computeResultCalled);

}

private class FakeUserInterface implements CalculatorContract.IUserInterface{
boolean displayUpdateCalled = false;
boolean showErrorCalled = false;
String displayValueInitial = “5+5”;
String displayValueFinal = “”;

@Override
public void updateDisplay(String displayText) {
displayUpdateCalled = true;
displayValueFinal = displayText;
}

@Override
public String getDisplay() {
return displayValueInitial;
}

@Override
public void showError() {
showErrorCalled = true;
}
}

private class FakeComputationLogic implements CalculatorContract.IComputationLogic{
boolean computeResultCalled = false;
boolean returnEmpty = false;

@Override
public Optional computeResult(String expression) {
computeResultCalled = true;
if (returnEmpty) return Optional.empty();
else return Optional.of(“10.0”);
}
}
}

As you can see, not only can this test suite be executed very rapidly, but it did not take very much time at all to write. In any case, we will now look at some more subtle things which made writing this test class very easy.

The Power Of Abstraction And Dependency Inversion

There are two other important concepts which have been applied to CalculatorControlLogic which have made it trivially easy to test. Firstly, if you have ever wondered what the benefits of using Interfaces and Abstract Classes (collectively referred to as abstractions) in Java are, the code above is a direct demonstration. Since the class to be tested references abstractions instead of concrete classes, we were able to create Fake test doubles for the user interface and back end from within our test class. As long as these test doubles implement the appropriate interfaces, CalculatorControlLogiccould not care less that they are not the real thing.

Secondly, CalculatorControlLogichas been given its dependencies via the constructor (yes, that is a form of Dependency Injection), instead of creating its own dependencies. Therefore, it does not need to be re-written when used in a production or testing environment, which is a bonus for efficiency.

Dependency Injection is a form of Inversion Of Control, which is a tricky concept to define in plain language. Whether you use Dependency Injection or a Service Locator Pattern, they both achieve what Martin Fowler (my favourite teacher on such topics) describes as “the principle of separating configuration from use.” This results in classes which are easier to test, and easier to build in isolation from one another.

Testing Computation Logic

Finally, we come to the ComputationLogic class, which is supposed to approximate an IO device such as an adapter to a remote server, or a local database. Since we need neither of those for a simple calculator, it will just be responsible for encapsulating the logic required to validate and evaluate the expressions we give it:

public class CalculatorComputationLogic implements CalculatorContract.IComputationLogic {

private final char ADD = ‘+’;
private final char SUBTRACT = ‘-‘;
private final char MULTIPLY = ‘*’;
private final char DIVIDE = ‘/’;

@Override
public Optional computeResult(String expression) {
if (hasOperator(expression)) return attemptEvaluation(expression);
else return Optional.empty();

}

private Optional attemptEvaluation(String expression) {
String delimiter = getOperator(expression);
Binomial b = buildBinomial(expression, delimiter);
return evaluateBinomial(b);
}

private Optional evaluateBinomial(Binomial b) {
String result;
switch (b.getOperatorChar()) {
case ADD:
result = Double.toString(b.firstTerm + b.secondTerm);
break;
case SUBTRACT:
result = Double.toString(b.firstTerm – b.secondTerm);
break;
case MULTIPLY:
result = Double.toString(b.firstTerm * b.secondTerm);
break;
case DIVIDE:
result = Double.toString(b.firstTerm / b.secondTerm);
break;
default:
return Optional.empty();
}
return Optional.of(result);
}

private Binomial buildBinomial(String expression, String delimiter) {
String[] operands = expression.split(delimiter);
return new Binomial(
delimiter,
Double.parseDouble(operands[0]),
Double.parseDouble(operands[1])
);
}

private String getOperator(String expression) {
for (char c : expression.toCharArray()) {
if (c == ADD || c == SUBTRACT || c == MULTIPLY || c == DIVIDE)
return “\” + c;
}

//default
return “+”;
}

private boolean hasOperator(String expression) {
for (char c : expression.toCharArray()) {
if (c == ADD || c == SUBTRACT || c == MULTIPLY || c == DIVIDE) return true;
}
return false;
}

private class Binomial {
String operator;
double firstTerm;
double secondTerm;

Binomial(String operator, double firstTerm, double secondTerm) {
this.operator = operator;
this.firstTerm = firstTerm;
this.secondTerm = secondTerm;
}

char getOperatorChar(){
return operator.charAt(operator.length() – 1);
}
}

}

There is not too much to say about this class since typically there would be some tight coupling to a particular back-end library which would present similar problems as a class tightly coupled to Android. In a moment we will discuss what to do about such classes, but this one is so easy to test that we may as well have a try:

public class CalculatorComputationLogicTest {

private CalculatorComputationLogic comp = new CalculatorComputationLogic();

@Test
public void additionTest() {
String EXPRESSION = “5+5”;
String ANSWER = “10.0”;

Optional result = comp.computeResult(EXPRESSION);

assertTrue(result.isPresent());
assertEquals(result.get(), ANSWER);
}

@Test
public void subtractTest() {
String EXPRESSION = “5-5”;
String ANSWER = “0.0”;

Optional result = comp.computeResult(EXPRESSION);

assertTrue(result.isPresent());
assertEquals(result.get(), ANSWER);
}

@Test
public void multiplyTest() {
String EXPRESSION = “5*5”;
String ANSWER = “25.0”;

Optional result = comp.computeResult(EXPRESSION);

assertTrue(result.isPresent());
assertEquals(result.get(), ANSWER);
}

@Test
public void divideTest() {
String EXPRESSION = “5/5”;
String ANSWER = “1.0”;

Optional result = comp.computeResult(EXPRESSION);

assertTrue(result.isPresent());
assertEquals(result.get(), ANSWER);
}

@Test
public void invalidTest() {
String EXPRESSION = “Potato”;

Optional result = comp.computeResult(EXPRESSION);

assertTrue(!result.isPresent());
}
}

The easiest classes to test, are those which are simply given some value or object, and are expected to return a result without the necessity of calling some external dependencies. In any case, there comes a point where no matter how much software architecture wizardry you apply, you will still need to worry about classes which cannot be decoupled from platforms and frameworks. Fortunately, there is still a way we can employ software architecture to: At worst make these classes easier to test, and at best, so trivially simple that testing can be done at a glance.

Humble Objects And Passive Views

The above two names refer to a pattern in which an object that must talk to low-level dependencies, is simplified so much that it arguably does not need to be tested. I was first introduced to this pattern via Martin Fowler’s blog on variations of Model-View-Presenter. Later on, through Robert C. Martin’s works, I was introduced to the idea of treating certain classes as Humble Objects, which implies that this pattern does not need to be limited to user interface classes (although I do not mean to say that Fowler ever implied such a limitation).

Whatever you choose to call this pattern, it is delightfully simple to understand, and in some sense I believe it is actually just the result of rigorously applying SOC to your classes. While this pattern applies also to back end classes, we will use our user interface class to demonstrate this principle in action. The separation is very simple: Classes which interact with platform and framework dependencies, do not think for themselves (hence the monikers Humble and Passive). When an event occurs, the only thing they do is forward the details of this event to whatever logic class happens to be listening:

//from CalculatorActivity’s onCreate() function:
evaluate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
controlLogic.handleInput(‘=’);
}
});

The logic class, which should be trivially easy to test, is then responsible for controlling the user interface in a very fine-grained manner. Rather than calling a single generic updateUserInterface(…) function on the user interface class and leaving it to do the work of a bulk update, the user interface (or other such class) will possess small and specific functions which should be easy to name and implement:

//Interface functions of CalculatorActivity:
@Override
public void updateDisplay(String displayText) {
display.setText(displayText);
}

@Override
public String getDisplay() {
return display.getText().toString();
}

@Override
public void showError() {
Toast.makeText(this, INVALID_MESSAGE, Toast.LENGTH_LONG).show();
}
//…

In principal, these two examples ought to give you enough to understand how to go about implementing this pattern. The object which possesses the logic is loosely coupled, and the object which is tightly coupled to pesky dependencies becomes almost devoid of logic.

Now, at the start of this subsection, I made the statement that these classes become arguably unnecessary to test, and it is important we look at both sides of this argument. In an absolute sense, it is impossible to achieve 100% test coverage by employing this pattern, unless you still write tests for such humble/passive classes. It is also worth noting that my decision to use a Calculator as an example App, means that I cannot escape having a gigantic mass of findViewById(…) calls present in the Activity. Giant masses of repetitive code are a common cause of typing errors, and in the absence of some Android UI testing frameworks, my only recourse for testing would be via deploying the feature to a device and manually testing each interaction. Ouch.

It is at this point that I will humbly say that I do not know if 100% code coverage is absolutely necessary. I do not know many developers who strive for absolute test coverage in production code, and I have never done so myself. One day I might, but I will reserve my opinions on this matter until I have the reference experiences to back them up. In any case, I would argue that applying this pattern will still ultimately make it simpler and easier to test tightly coupled classes; if for no reason other than they become simpler to write.

Another objection to this approach, was raised by a fellow programmer when I described this approach in another context. The objection was that the logic class (whether it be a Controller, Presenter, or even a ViewModel depending on how you use it), becomes a God class.

While I do not agree with that sentiment, I do agree that the end result of applying this pattern is that your Logic classes become larger than if you left more decisions up to your user interface class.

This has never been an issue for me as I treat each feature of my applications as self-contained components, as opposed to having one giant controller for managing multiple user interface screens. In any case, I think this argument holds reasonably true if you fail to apply SOC to your front end or back end components. Therefore, my advice is to apply SOC to your front end and back end components quite rigorously.

Further Considerations

After all of this discussion on applying the principles of software architecture to reduce the necessity of using a wide-array of testing frameworks, improve the testability of classes in general, and a pattern which allows classes to be tested indirectly (at least to some degree), I am not actually here to tell you to stop using your preferred frameworks.

For those curious, I often use a library to generate mock classes for my Unit tests (for Java I prefer Mockito, but these days I mostly write Kotlin and prefer Mockk in that language), and JUnit is a framework which I use quite invariably. Since all of these options are coupled to languages as opposed to the Android platform, I can use them quite interchangeably across mobile and web application development. From time to time (if project requirements demand it), I will even use tools like Robolectric, MockWebServer, and in my five years of studying Android, I did begrudgingly use Espresso once.

My hope is that in reading this article, anyone who has experienced a similar degree of aversion to testing due to paralysis by jargon analysis, will come to see that getting started with testing really can be simple and framework minimal.

Further Reading on SmashingMag:

Sliding In And Out Of Vue.js
Designing And Building A Progressive Web Application Without A Framework
CSS Frameworks Or CSS Grid: What Should I Use For My Project?
Using Google’s Flutter For Truly Cross-Platform Mobile Development

Smashing Editorial
(dm, il)

Moment dropping a 37mm Cinema Filters for your phone, no lens needed.

Original Source: http://feedproxy.google.com/~r/abduzeedo/~3/pTAMn4qU4vk/moment-dropping-37mm-cinema-filters-your-phone-no-lens-needed

Moment dropping a 37mm Cinema Filters for your phone, no lens needed.
Moment dropping a 37mm Cinema Filters for your phone, no lens needed.

AoiroStudioAug 22, 2019

Moment is easily one of my favorite brands out there, we have witnessed their early beginnings to this uplifting brand always making awesome new products and involving the community right to its core. If you don’t know what Moment is and love mobile photography and filmmaking, check them out now. We are featuring today their new 37mm cinema filters for your phone, to polarize light, leaving you with a better image that you can’t replicate post-production. I might get this one for my collection.

Mobile Filmmaking

37mm Cine Phone Filter Complete Set

Moment dropping a 37mm Cinema Filters for your phone, no lens needed. Moment dropping a 37mm Cinema Filters for your phone, no lens needed. Moment dropping a 37mm Cinema Filters for your phone, no lens needed.

Java Compact Shoulder Bag

Moment dropping a 37mm Cinema Filters for your phone, no lens needed.

Java Mini Hip Pack

Moment dropping a 37mm Cinema Filters for your phone, no lens needed.

Groove Compact Shoulder Bag

Moment dropping a 37mm Cinema Filters for your phone, no lens needed.

Groove Deluxe Hip Pack

Moment dropping a 37mm Cinema Filters for your phone, no lens needed.

Midnight Compact Shoulder Bag

Moment dropping a 37mm Cinema Filters for your phone, no lens needed.

Midnight Basic Hip Pack

Moment dropping a 37mm Cinema Filters for your phone, no lens needed.

Shop on Moment