项目作者: cloudacademy

项目描述 :
Java JDK11 TDD Bitcoin Converter Project
高级语言: Java
项目地址: git://github.com/cloudacademy/java-tdd-bitcoinconverter.git
创建时间: 2020-10-19T00:36:41Z
项目社区:https://github.com/cloudacademy/java-tdd-bitcoinconverter

开源协议:

下载


Java JDK11 TDD Bitcoin Converter

dev.build prod.build code coverage

Background

The following repo contains source code developed using TDD (Test Driven Development) practices. The sample project implements a Java (JDK 11) library which interacts with the Bitcoin Price Index api.

Bitcoin Converter Architecture

Note: If you intend to follow along and complete the full demonstration then please fork or setup a new GitHub repo - as step 6 will require you to create a GitHub Secret to store the Coveralls project token. Coveralls is used to create code coverage reports and visuals.

:metal:

Prerequisites

JDK11 and Maven3 are required for this project

All provided sample code and instructions have been tested with the following versions:

  • JDK11
  1. java -version
  2. openjdk version "11.0.9" 2020-10-20
  3. OpenJDK Runtime Environment (build 11.0.9+11)
  4. OpenJDK 64-Bit Server VM (build 11.0.9+11, mixed mode)
  • Maven3
  1. mvn --version
  2. Apache Maven 3.9.3 (21122926829f1ead511c958d89bd2f672198ae9f)
  3. Maven home: /opt/maven
  4. Java version: 11.0.19, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
  5. Default locale: en, platform encoding: UTF-8
  6. OS name: "linux", version: "4.15.0-212-generic", arch: "amd64", family: "unix"

Tools and Frameworks

The following tools and frameworks have been used to perform the TDD developement:

  • Maven - used to provide build and test project automation and management
  • JUnit5 - a unit testing framework, used to implement unit tests
  • Mockito - a mocking library, used to create mocks for external dependencies
  • GitHub Actions - used to provide CICD features for automated building and testing
  • Coveralls - used to provide unit test code coverage reports

JDK11 and JUnit5 Maven Archetype

The following custom Maven Archetype has been made available - this can used to create new JDK11 and JUnit5 based projects:

https://github.com/cloudacademy/java11-junit5-archetype

Repo Branches

Branches are used within this repo to demonstrate the TDD workflow (red, green, refactor), as well as highlighting other project management configuration areas. These branches allow you to quickly jump ahead to the area of interest:

Branches

  • step1 - demonstrates how to setup the initial project structure with the first set of unit tests using JUnit5 and the @Test annotation, uses a fake implementation of the Bitcoin Price Index API

  • step2 - refactors current unit tests and codebase to call the real Bitcoin Price Index API using the Apache HttpClient for HTTP access - the tests in this step will fail, this introduces you to the next step (mocks)

  • step3 - introduces Mockito and refactors current unit tests to mock the Apache HttpClient HTTP calls to the Bitcoin Price Index API

  • step4 - refactors the unit tests and codebase to add addtional unit tests to test error conditions

  • step5 - adds in a GitHub Action workflow to perform automatic build and tests on push events - produces a jar artifact

  • step6 - refactors the single GitHub Action workflow into seperate Dev and Prod GitHub Action workflows - the Dev workflow generates a unit test code coverage report and forwards it automatically into https://coveralls.io/ for viewing and analysis - the Prod workflow is used to produce releases

  • step7 - introduces a client console project to test the GitHub Action built jar library artifact

Note: The main branch (this branch) contains the same code and configuration as contained in the step7 branch

Bitcoin Converter Library

This project builds a Java library which contains the following 2 public methods:

  1. public double getExchangeRate(Currency currency)

returns in realtime the current Bitcoin exchange rate for the given currency (USD, GBP, or EUR)

  1. public double convertBitcoins(Currency currency, double coins) throws IllegalArgumentException

returns the dollar value for the given currency (USD, GBP, or EUR), and the number of Bitcoins

To build the Bitcoin Converter Library perform the following commands:

  1. mvn clean compile test package

Bitcoin Converter Client

This project also contains a sample client console based application - which imports the Bitcoin Converter library. To build and run the client perform the following commands:

  1. {
  2. cd client
  3. #install bitcoin lib
  4. FILE=`ls libs/`
  5. VERSION=`echo $FILE | egrep -o "([0-9]{1,}\.)+[0-9]{1,}-\w*"`
  6. mvn install:install-file \
  7. -Dfile=./libs/$FILE \
  8. -DgroupId=com.cloudacademy \
  9. -DartifactId=bitcoin-converter-svc-lib \
  10. -Dversion=$VERSION \
  11. -Dpackaging=jar
  12. #build and package console app
  13. mvn clean package
  14. #execute console app
  15. java -jar target/bitcoin-converter-client-1.0.0-SNAPSHOT-jar-with-dependencies.jar
  16. }

GitHub Action - CICD

This project demonstrates how to use GitHub Actions to perform automated builds, testing, packaging, and releases.

dev.build.yml

  1. name: Java CI Dev
  2. on:
  3. push:
  4. branches: main
  5. jobs:
  6. build:
  7. runs-on: ubuntu-latest
  8. steps:
  9. - uses: actions/checkout@v2
  10. - name: JDK 1.11 Install
  11. uses: actions/setup-java@v1
  12. with:
  13. java-version: 11
  14. - name: Maven Build
  15. run: |
  16. mvn -B clean package
  17. mkdir staging
  18. cp target/*.jar staging
  19. - name: Code Coverage
  20. run: |
  21. mvn -B jacoco:prepare-agent clean test jacoco:report coveralls:report -Dcoveralls.secret=${{ secrets.COVERALLS }}
  22. - name: Artifact Upload
  23. uses: actions/upload-artifact@v2
  24. with:
  25. name: Package
  26. path: staging

prod.build.yml

  1. name: Java CI Prod
  2. on:
  3. push:
  4. tags:
  5. - '*'
  6. jobs:
  7. build:
  8. runs-on: ubuntu-latest
  9. steps:
  10. - uses: actions/checkout@v2
  11. - name: JDK 1.11 Install
  12. uses: actions/setup-java@v1
  13. with:
  14. java-version: 11
  15. - name: Maven Build
  16. run: |
  17. mvn versions:set -DremoveSnapshot
  18. mvn -B clean package test
  19. mkdir release
  20. cp target/*.jar release
  21. - name: Artifact Upload
  22. uses: actions/upload-artifact@v2
  23. with:
  24. name: Package
  25. path: release
  26. - name: Make Release
  27. uses: softprops/action-gh-release@v0.1.5
  28. with:
  29. files:
  30. target/*.jar
  31. env:
  32. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Coveralls - Code Coverage Report

This project forwards its unit testing code coverage reports to coveralls.io for report viewing and analysis.

Vagrant

The provided Vagrantfile can be used to spin up an Ubuntu 18.04 instance, which is bootstrapped to install both OpenJDK 11 and Maven 3.6.3:

  1. $bootstrap = <<SCRIPT
  2. export DEBIAN_FRONTEND=noninteractive
  3. export APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1
  4. apt-get update
  5. apt-get install -y tree
  6. echo ========================
  7. echo installing openjdk-11-jdk...
  8. apt-get install -y openjdk-11-jdk
  9. echo ========================
  10. echo installing LATEST maven ...
  11. cd /tmp
  12. LATEST_SEMVER=$(curl -s https://repo1.maven.org/maven2/org/apache/maven/maven/maven-metadata.xml \
  13. | grep "<version>3.*</version>" \
  14. | tr -s " " \
  15. | cut -d ">" -f2 \
  16. | cut -d "<" -f1 \
  17. | sort -V -r \
  18. | head -1)
  19. LATEST_SEMVER=${LATEST_SEMVER:=3.9.3} # default to 3.9.3 if not detected in previous step
  20. echo downloading https://dlcdn.apache.org/maven/maven-3/$LATEST_SEMVER/binaries/apache-maven-$LATEST_SEMVER-bin.tar.gz ...
  21. curl -OLs --output /dev/null https://dlcdn.apache.org/maven/maven-3/$LATEST_SEMVER/binaries/apache-maven-$LATEST_SEMVER-bin.tar.gz
  22. tar xf /tmp/apache-maven-*.tar.gz -C /opt
  23. ln -s /opt/apache-maven-$LATEST_SEMVER /opt/maven
  24. cat <<EOF >> /etc/profile.d/maven.sh
  25. export JAVA_HOME=/usr/lib/jvm/java-1.11.0-openjdk-amd64
  26. export M2_HOME=/opt/maven
  27. export MAVEN_HOME=/opt/maven
  28. export PATH=/opt/maven/bin:${PATH}
  29. EOF
  30. chmod +x /etc/profile.d/maven.sh
  31. source /etc/profile.d/maven.sh
  32. echo ========================
  33. echo finished ...
  34. SCRIPT
  35. Vagrant.configure("2") do |config|
  36. config.vm.box = "ubuntu/bionic64"
  37. config.vm.provision "shell", inline: $bootstrap
  38. end

Use the following Vagrant command to launch the instance:

  1. vagrant up

Then SSH into the instance by running the following command:

  1. vagrant ssh

To confirm that both the OpenJDK 11 JDK and Maven 3.6.3 have been installed successfully by the boostrapping, run the following command:

  1. java -version
  2. mvn -version

Back on your local workstation, you can use Visual Studio Code or any other editor to open and modify the contents of the current folder - with all changes being automatically synced back into the /vagrant directory within the Vagrant instance.