Ứng dụng khách di động: cài đặt, gỡ lỗi, lắp ráp cho Android." Tôi gặp khó khăn như thế nào trong cấu hình "trình tạo ứng dụng di động" Xây dựng ứng dụng di động 1c

Tôi nhớ khoảng thời gian tuyệt vời đó khi tập hợp phiên bản phát hành của một ứng dụng di động là bạn phải đặt debug = false và bắt đầu xuất tệp apk. 2 phút trôi qua trong khi IDE hoạt động và mọi thứ đã sẵn sàng. Mọi nỗ lực đều tập trung vào nhu cầu chỉ định dữ liệu chứng chỉ ký. Điều này xảy ra khá gần đây. Giờ đây, quá trình xây dựng chính ứng dụng đó đã phát triển đến mức nếu tôi đột nhiên cần tự mình thực hiện tất cả các thao tác và ngay cả khi tôi nhớ mọi thứ và làm đúng (điều mà tôi không tin vào), sẽ không mất một giờ , mà hôm nay có vẻ quá dài, và rất có thể là một ngày, sau đó bác sĩ trị liệu sẽ phải kê đơn cho tôi nghỉ ốm vì mệt mỏi trong hai tuần.

Vì vậy, quá trình xây dựng một ứng dụng di động. Tôi sẽ cố gắng cho bạn biết nó bao gồm những gì - không phải vì gần đây việc đăng bài về CI của đội di động này hay đội di động kia đã trở thành mốt (với poker, nàng tiên cá và các thuộc tính bắt buộc khác), mà bởi vì đây là một trải nghiệm tuyệt vời mà tôi có được , làm việc trên Mail.Ru Mail cho Android và vì cơ hội này rất có thể sẽ không tồn tại nếu tôi làm việc trong một nhóm khác, trong một dự án khác hoặc ở một công ty khác.

Đối với bất kỳ quy trình nào, một quyết định quan trọng là lựa chọn hệ thống mà toàn bộ tổ hợp sẽ được xây dựng trên đó. Các bản dựng phải được xử lý bởi máy chủ bản dựng. Nó hợp lý. Nhưng chọn cái nào?

Câu hỏi không rõ ràng, mọi người chọn giải pháp này hoặc giải pháp khác dựa trên kinh nghiệm của họ, các nhiệm vụ mà hệ thống phải đối mặt và nguồn lực họ có. Một số người thích các giải pháp miễn phí vì họ không phải giải thích với sếp tại sao bạn cần 000 đô la một năm và tại sao bạn không thể làm được nếu không có nó. Một số được thúc đẩy bởi sự hiện diện của cộng đồng hoặc kinh nghiệm của một số lượng lớn các nhóm đã sử dụng các giải pháp này và hài lòng với kết quả. Số lượng quan điểm có xu hướng phù hợp với số lượng người đã hỏi câu hỏi này. Tôi không thể nói rằng lập luận của ai đó là hợp lý hoặc sự phản đối của ai đó là không liên quan. Tuy nhiên, bất kể quan điểm của nhà phát triển đang gặp phải vấn đề như vậy là gì, đa số sẽ đồng ý rằng nhìn chung, tất cả các giải pháp phổ biến trên thị trường chỉ khác nhau về tính dễ cấu hình, tích hợp với các hệ thống liên quan, khả năng mở rộng và hỗ trợ từ cộng đồng hoặc nhà phát triển hệ thống.

Nói chung, việc chọn máy chủ xây dựng là một chủ đề để thảo luận riêng. Hãy để tôi nói rằng chúng tôi đã chọn giải pháp Bamboo Build Server của Atlassian. Có một số lý do chính, một trong số đó là sự dễ dàng tích hợp với trình theo dõi vấn đề mà chúng tôi sử dụng trong dự án, cũng như với hệ thống lưu trữ kho lưu trữ và đánh giá mã. Các chàng trai rất giỏi ở khoản này: mọi thứ đều thuận tiện, mọi thứ đều trong tầm tay và quan trọng nhất là hầu hết tất cả các giải pháp và tùy chọn được cung cấp đều hoàn toàn phù hợp với quá trình phát triển của nhóm chúng tôi

Cây tre

Bamboo là một giải pháp rất phổ biến và được rất nhiều đội trên khắp thế giới sử dụng. Bạn có thể tìm thấy mô tả chi tiết về cách hoạt động của Công cụ CI/CD này trên trang web tài liệu chính thức, nhưng tôi sẽ cho phép mình dịch tự do một phần nhỏ của tài liệu này để tránh sự khác biệt về thuật ngữ.

Nhiệm vụ của máy chủ Tích hợp liên tục là thực hiện tất cả các công việc lắp ráp, thử nghiệm và triển khai vào môi trường thử nghiệm của dự án. Máy chủ CI liên hệ với kho lưu trữ, nhận bản sửa đổi cụ thể của dự án, thực hiện tất cả các hành động cần thiết và cung cấp kết quả xây dựng hoàn chỉnh cho nhóm dự án.

Dự án
  • bao gồm một hoặc nhiều kế hoạch xây dựng
  • cung cấp một báo cáo về tất cả các kế hoạch xây dựng dự án
  • liên kết với các ứng dụng khác (Jira, Fisheye, Crucible, Stash)
Xây dựng kế hoạch
(Kế hoạch)
  • bao gồm một hoặc nhiều giai đoạn (giai đoạn)
  • tất cả các giai đoạn được khởi chạy tuần tự, sử dụng cùng một kho lưu trữ
  • chứa các quy tắc để khởi chạy các bản dựng, tùy thuộc vào các kế hoạch xây dựng dự án khác
Sân khấu
(Sân khấu)
  • bao gồm một hoặc nhiều tác phẩm
  • thực hiện công việc song song, trên các tác nhân xây dựng miễn phí, nó được coi là hoàn thành khi tất cả công việc được hoàn thành thành công
  • chuyển các tạo phẩm sang các giai đoạn xây dựng tiếp theo.
Công việc
(Công việc)
  • bao gồm một hoặc nhiều nhiệm vụ
  • tất cả các tác vụ bên trong được thực hiện tuần tự trên cùng một tác nhân
Nhiệm vụ
(Nhiệm vụ)
  • hoạt động riêng biệt, chẳng hạn như kiểm tra bản sửa đổi dự án, chạy tập lệnh, v.v.


Các bộ phận tương tự ít nhiều đều có sẵn trong bất kỳ hệ thống lắp ráp nào và mang lại sự linh hoạt cần thiết trong việc thiết kế toàn bộ quy trình. Thoạt nhìn điều này có vẻ như quá phức tạp. Đây là trường hợp của dự án của chúng tôi khi chúng tôi mới bắt đầu sử dụng Bamboo, nhưng dần dần mọi thứ đã ổn định, chúng tôi hiểu rõ ràng phần nào của toàn bộ quá trình lắp ráp nên được thu nhỏ lại, phần nào nên được tách biệt và một cấu trúc khá hài hòa được phát triển trong khuôn khổ của các khái niệm được đề xuất.

Nói chung, bạn cần hiểu rõ rằng build server hay CI server là một phần quan trọng trong việc tự động hóa quá trình phát triển phần mềm. Bằng cách giao cho mô-đun này tất cả các nhiệm vụ và công việc cần thực hiện ở các giai đoạn và cấp độ khác nhau trong quá trình chuẩn bị ứng dụng để phát hành trên thị trường, chúng ta sẽ có được một loại Đường ống phát hành ứng dụng. Ngược lại, nó giúp bạn có thể dễ dàng xác định những tác vụ nào được bao gồm trong một bản dựng cụ thể, bản phát hành hiện đang ở giai đoạn nào, những vấn đề nào phát sinh khi tích hợp chức năng mới, chúng ta đang ở giai đoạn chuẩn bị hotfix nào, v.v.

Vì vậy, chúng tôi dần dần tiếp cận mô tả về cách thực hiện điều này trong nhóm của chúng tôi.

Nhiệm vụ

Dự án xây dựng của chúng tôi được chia thành nhiều giai đoạn, phản ánh các nhiệm vụ chính tại thời điểm này:
  • Lắp ráp - bao gồm tất cả các tùy chọn lắp ráp có thể cần thiết trong quá trình phát hành: alpha, beta, phát hành. Vâng, vâng, chính các nhóm dự án khác nhau giữa chúng ta chứ không chỉ là trạng thái của chúng. Sự khác biệt của sản phẩm: tài nguyên khác nhau, sự hiện diện hay vắng mặt của cài đặt, v.v.
  • Xác minh là phần phức tạp nhất về mặt kỹ thuật và năng lực trong toàn bộ giai đoạn lắp ráp ứng dụng: phân tích mã tĩnh, kiểm tra đơn vị, kiểm tra giao diện người dùng chức năng, kiểm tra bản địa hóa.
  • Triển khai. Hiện đã được trừu tượng hóa khỏi toàn bộ hội đồng, nó có vẻ như đang ở bên cạnh. Do đó, nếu cần, chúng tôi có thể triển khai mọi bản sửa đổi/nhánh/loại ứng dụng cho bất kỳ môi trường nào (alpha, beta, phát hành).
Về nguyên tắc, đây là lúc câu chuyện có thể kết thúc, nhưng có lẽ tôi sẽ xen vào và cung cấp chi tiết.

Cuộc họp

Bây giờ chúng tôi đang phát triển ba dự án cùng một lúc với một cơ sở mã duy nhất, hãy gọi chúng là Dự án 1, Dự án 2 và Dự án 3. Tất nhiên, sự khác biệt giữa chúng không quá lớn như giữa cờ vua và máy nghe nhạc, vì cả ba sản phẩm đều thuộc về nhau. vào danh mục ứng dụng email. Tuy nhiên, chúng có thiết kế khác nhau, có sự khác biệt về chức năng và chúng tương tác với máy chủ một cách khác nhau. Tất cả điều này chỉ ra các yêu cầu của nó đối với việc lắp ráp, thử nghiệm và phát triển sản phẩm.

Quy trình làm việc của nhánh tính năng

Mọi quá trình xây dựng đều bắt đầu bằng việc kiểm tra bản sửa đổi dự án từ hệ thống kiểm soát phiên bản. Có vẻ như, tại sao lại tập trung vào điều này - sau tất cả, mọi người đều có thể thanh toán? Thật sự. Nhưng việc này nên được thực hiện từ chi nhánh nào?

Chúng tôi sử dụng Quy trình làm việc của Chi nhánh tính năng để làm việc trên sản phẩm. Bạn có thể đọc riêng về phương pháp này. Ưu điểm chính của nó đối với tôi là sự cô lập của các thay đổi. Với cách tiếp cận này, mỗi nhà phát triển có thể, trong khuôn khổ nhiệm vụ, chuyển giao ít nhất toàn bộ dự án, gửi nó để thử nghiệm và nếu QA chấp thuận, thì mã đã được thử nghiệm và hoạt động sẽ được đưa vào nhánh chung. Cách tiếp cận này giảm thiểu nguy cơ lỗi xuất hiện trong bản phát hành, do thực tế là chuỗi hành động được xác định: kiểm tra đầu tiên, sau đó hợp nhất vào nhánh chính của dự án.

Để kiểm tra những thay đổi riêng biệt này, chúng tôi phải có một bản dựng mà chúng tôi có thể chạy kiểm tra tự động trên đó và chúng tôi gửi bản dựng đó để kiểm tra thủ công nhằm được nhóm QA phê duyệt. Bamboo cung cấp giải pháp bạn cần cho việc này ngay lập tức. Nó được gọi là Sơ đồ chi nhánh và bao gồm việc xác định một nhánh chính cho bản dựng (ví dụ: alpha) và tất cả các nhánh khớp với mẫu đã chỉ định đều được coi là một nhánh tính năng. Một bản sao của kế hoạch xây dựng được tạo cho họ, nhưng điểm khác biệt là việc kiểm tra sẽ diễn ra từ nhánh này chứ không phải từ nhánh chính của kế hoạch xây dựng. Nó trông giống như thế này.

Trong chế độ xem kế hoạch xây dựng, chúng ta có thể chuyển đổi giữa nhánh chính và nhánh hiện có, xem kết quả của tất cả các trạng thái cục bộ.

Bản thân kế hoạch chi nhánh trông giống nhau, ngoại trừ việc nó có liên kết đến nhiệm vụ.

Với dòng chảy như vậy, thread chắc chắn sẽ bắt đầu trở nên lỗi thời kể từ thời điểm nó được tạo ra. Để sớm phát hiện xung đột với nhánh chính để kiểm tra mã mới nhất, bạn cần liên tục cập nhật nhánh của mình trong quá trình phát triển. Bamboo có thể tự động thực hiện việc này trước khi bắt đầu xây dựng dự án. Trong trường hợp xảy ra xung đột, bản dựng sẽ không được thực hiện và nhà phát triển trước tiên sẽ phải cập nhật nhánh của mình rồi thực hiện những thay đổi này. Sau đó sẽ không có xung đột trước khi lắp ráp và mọi thứ sẽ diễn ra như bình thường.

Hương vị sản phẩm

Giả sử chúng ta có một dự án cần được tập hợp thành nhiều biến thể, thay đổi tài nguyên, mã và cấu hình. Có một số tùy chọn về cách thực hiện điều này. Chúng tôi được hướng dẫn bởi thực tế là tất cả các điều kiện xây dựng, tất cả cấu hình và các phần mô tả khác phải có trong tập lệnh xây dựng. Trong trường hợp của chúng tôi, Gradle là lý tưởng để giải quyết vấn đề này. Có một plugin Android tốt cho nó, cho phép bạn cấu hình linh hoạt hầu hết các tham số tiêu chuẩn và phi tiêu chuẩn để lắp ráp một dự án phức tạp.

Hãy cùng xem có bao nhiêu tùy chọn lắp ráp mà chúng tôi tích cực sử dụng và hỗ trợ.

Hãy bắt đầu với thực tế là chúng tôi có ba Hương vị Sản phẩm chính: Dự án 1, Dự án 2 và Dự án 3.

Hương vị sản phẩm là đại diện của một nhánh sản phẩm. Trong hầu hết các trường hợp, đây là những ứng dụng khác nhau có các gói khác nhau, chứng chỉ ký khác nhau, nguồn và tài nguyên khác nhau. Đối với mỗi ứng dụng, chúng tôi có một số tùy chọn xây dựng, cụ thể là:

  • gỡ lỗi- được ký bằng khóa gỡ lỗi, có thể được gỡ lỗi, không bị xáo trộn;
  • alpha/alpha nhánh- tập hợp bị xáo trộn, khác nhau về cấu hình cho phân tích, tập hợp sự cố, tài nguyên, cài đặt gỡ lỗi có sẵn trong ứng dụng;
  • tập đoàn beta- phiên bản beta, có bật nhật ký, có sẵn chế độ gỡ lỗi;
  • phiên bản beta- một bản dựng càng gần với bản phát hành càng tốt, được phân biệt bằng phân tích, thu thập sự cố, đã tắt nhật ký, chế độ gỡ lỗi và không có cài đặt gỡ lỗi;
  • giải phóng- phiên bản sản xuất của ứng dụng, hầu hết tất cả các tùy chọn bổ sung đều bị tắt, bộ sưu tập phân tích và thống kê được định cấu hình cho các dự án chiến đấu trong các hệ thống này, v.v.;
  • kiểm thử đơn vị/giao diện người dùng- các tập hợp có bảng kê khai bị ghi đè, ví dụ: cho phép bật quyền đọc SMS cần thiết để kiểm tra đăng nhập tự động (ủy quyền, đăng ký, xác thực hai yếu tố) bằng mã SMS.
Tổng cộng:

8 loại bản dựng * 3 hương vị sản phẩm = 24 biến thể ứng dụng

Tại sao nhiều như vậy? Tôi sẽ cố gắng trả lời. Một trong những thách thức điển hình mà bạn phải giải quyết khi có ba sản phẩm khác nhau được xuất bản sang các môi trường khác nhau là phân tách các phân tích. Và điều này phải được thực hiện, nếu không số liệu thống kê từ phiên bản alpha của ứng dụng sẽ làm sai lệch hình ảnh hiện có trong quá trình sản xuất. Chúng tôi sử dụng HockeyApp để thu thập số liệu thống kê về sự cố. Trong đó chúng tôi có các dự án riêng biệt cho các phương án lắp ráp khác nhau. Điều này giúp dễ dàng phân biệt, ví dụ: Dự án 1 gặp sự cố với Dự án 2 gặp sự cố, phiên bản beta với phiên bản phát hành, v.v.

Trong build.gradle của dự án của chúng tôi, cấu hình này trông như thế này.

ProductFlavors (project1 ( ... android.buildTypes ( alpha ( hockeyApp ( ) ) beta ( hockeyApp ( ) ) publicBeta ( ... ) phát hành ( ... ) ) project2 ( ... android.buildTypes ( alpha ( hockeyApp ( ) ) ... ) ) project3 ( ... android.buildTypes ( alpha ( hockeyApp ( ) ) ... ) )
Bằng cách này, chúng ta có thể định cấu hình các giá trị khác nhau cho bất kỳ tùy chọn xây dựng nào. Đối với tài nguyên và nguồn, nguyên tắc gần như giống nhau được sử dụng ở đây, ngoại trừ một tính năng: có thể hợp nhất các tài nguyên từ các tùy chọn khác nhau. Dự án của chúng tôi có các tài nguyên giống nhau cho tất cả các ứng dụng - ví dụ: bố cục của màn hình viết. Nếu các tệp như vậy phải được sao chép vào từng gói tài nguyên và được giữ riêng biệt thì khi thay đổi bố cục của màn hình viết thư, sẽ cần phải thay đổi tối đa ba tệp. May mắn thay, plugin gradle + android có thể hợp nhất các tài nguyên.

Tôi sẽ cho bạn biết chi tiết hơn một chút về cách điều này xảy ra - có lẽ ai đó sẽ có thể giải quyết các vấn đề hàng ngày của họ bằng cách sử dụng cách tiếp cận tương tự.

Chúng tôi đã xác định một số thư mục chứa tài nguyên (tất cả chúng đều nằm trong thư mục gốc của dự án).

  • độ phân giải- tài nguyên chung cho tất cả các biến thể ứng dụng: đây là các bộ chọn, đánh dấu, chủ đề, kiểu phổ biến, v.v.;
  • res_project1- tài nguyên dành riêng cho Dự án 1: hầu hết tất cả đồ họa được sử dụng trong ứng dụng đều nằm ở đây, các dòng chứa tên dự án, logo hoặc đánh dấu cụ thể - nói chung, mọi thứ chỉ liên quan đến Dự án 1;
  • res_project23- đây là một hình ảnh hơi khác: trong gói res _ dự án23 bao gồm tất cả các nguồn lực không giao nhau với Dự án nhưng giống nhau đối với Dự án 2 và Dự án 3. Việc phân nhóm các nguồn lực như vậy giúp giải quyết vấn đề khi sản phẩm của Dự án 2 và 3 rất giống nhau nhưng lại khá khác nhau từ Dự án 1. Nếu không, tôi sẽ phải sao chép các tài nguyên tương tự vào các thư mục res_project2 và res_project3;
  • res_project2- tài nguyên dành riêng cho Dự án 2: hiện tại đây là màu sắc, đồ họa, văn bản. Mọi thứ khác đều nằm trong gói chung;
  • res_project3- tương tự đối với Dự án 3, chỉ có một lựa chọn tài nguyên duy nhất cho ứng dụng này vẫn còn trong gói này.

Do đó, đối với mỗi tùy chọn xây dựng, chúng tôi hợp nhất một số gói để có được một bộ tài nguyên chung cho ứng dụng:

  • Dự án 1 = res + res_project1;
  • Dự án 2 = res + res_project23 + res_ project2;
  • Dự án 3 = res + res_project23 + res_ project3.
Đây là cơ sở. Để tùy chỉnh sâu hơn, chẳng hạn, bạn có thể thêm tài nguyên cụ thể, mã cho bản dựng thử nghiệm, v.v. Toàn bộ việc đóng cửa của chúng tôi với các nguồn trông giống như thế này:

SourceSets ( main (Manifest.srcFile "AndroidManifest.xml" java ( srcDir "src" loại trừ "**/instrumentTest/**" ) Resources.srcDirs = ["src"]aidl.srcDirs = ["src"] renderscript.srcDirs = ["src"] res.srcDirs = ["res"] assets.srcDirs = ["assets"] ) androidTest (Manifest.srcFile "src/instrumentTest/AndroidManifest.xml" java.srcDir "src/instrumentTest/Java" ) project2 ( res.srcDirs = ["res_project2", "res_project23"] java.srcDirs = ["src_common"] assets.srcDirs=["assets_ project2]Manifest.srcFile "res_ project23/AndroidManifest.xml" ) project3 ( res.srcDirs = ["res_project3", "res_ project23] assets.srcDirs=["assets_project3"] java.srcDirs = ["src_project3"]Manifest.srcFile "res_ project23/AndroidManifest.xml" ) project1 ( res.srcDirs = ["res_project1" ] java.srcDirs = ["src_common"] assets.srcDirs=["assets_project1"]Manifest.srcFile "res_project1/AndroidManifest.xml" ) testingUi (Manifest.srcFile "ui_testing/AndroidManifest.xml" ) )
Chỉ còn một chút việc phải làm thôi. Trong cấu hình dự án xây dựng, bạn cần chạy đúng tác vụ để có được .apk mong muốn, ví dụ: gradle AssembleProject1PublicBeta. Đương nhiên, với số lượng lớn các tùy chọn lắp ráp như vậy, chúng tôi quyết định không lắp ráp tất cả chúng một cách tuần tự mà song song hóa quy trình này. Tổng cộng, chúng tôi đã nhận được 6 công việc song song được thực hiện như một phần của giai đoạn lắp ráp. Mỗi tác phẩm xuất bản 3 hiện vật cho mỗi sản phẩm.

Tôi cho rằng những người đã đọc đến thời điểm này đều có câu hỏi: tại sao phải thu thập bản beta và phát hành với mỗi bản dựng dự án? Câu hỏi thực sự rất thú vị. Chúng tôi không đi đến quyết định này ngay lập tức mà sau một thời gian dài. Trong lịch sử, các bản beta và bản phát hành được xây dựng riêng biệt, sử dụng cùng một bản sửa đổi hoặc một hợp đồng nêu rõ rằng mã giống nhau. Sau đó, chúng tôi nhận ra rằng cách tiếp cận này có nhiều vấn đề và điều khó chịu nhất là bạn phát hiện ra trạng thái bản dựng sau khi quyết định xuất bản bản beta. Theo định luật Murphy, một cách tự nhiên, công trình có màu đỏ. Vì lý do nào. Càng nhiều thay đổi thì càng có nhiều khả năng chúng sẽ tác động tiêu cực đến công trình mà chúng ta không thể làm gì được. Bạn chỉ có thể rút ngắn khoảng thời gian từ thời điểm xảy ra lỗi đến thời điểm lỗi được phát hiện. Và lý tưởng nhất là hãy thực hiện việc này một cách tách biệt khỏi nhánh chung. Nếu chúng ta tách khỏi dự án và bản dựng phiên bản beta hoặc bản phát hành và xem xét quy trình tự động hóa, thì bây giờ tôi thấy một trong những chỉ số chính về chất lượng của toàn bộ phương pháp tự động hóa quy trình xây dựng, có lẽ là cơ hội để tìm hiểu về các vấn đề phát sinh càng nhanh càng tốt và quan trọng nhất là tìm hiểu TRƯỚC KHI những thay đổi này đi vào chi nhánh chung như thế nào.

Bài kiểm tra

Kiểm tra chất lượng tự động trong các ứng dụng di động chắc chắn là xu hướng của năm ngoái. Theo kinh nghiệm của tôi, đối với nhiều người điều này vẫn hơi phi thực tế. Mọi người đều nói về nó, nhưng hầu như không ai nhìn thấy nó. Chúng tôi đã giải quyết những nhiệm vụ như vậy trong khuôn khổ dự án của mình trong 2 năm và trong thời gian này, chúng tôi đã phát triển sự hiểu biết khá rõ ràng về hầu hết những điều phức tạp mà bất kỳ nhà phát triển nào cũng phải giải quyết. Tất cả những vấn đề và giải pháp này đều là một phân khúc khá mới và chưa ổn định đối với các ứng dụng di động, mặc dù web đã đi theo hướng này từ lâu và có đủ số lượng các giải pháp được tiêu chuẩn hóa.

Câu hỏi đầu tiên mà hầu hết mọi người đặt ra là: chúng ta sẽ tự động hóa cái gì? Nhà phát triển sẽ trả lời: chúng tôi sẽ kiểm tra mã, người quản lý sẽ ngay lập tức tranh luận rằng chức năng cần phải được kiểm tra. Tôi tin rằng cả hai đều cần phải được kiểm tra.

Nói chung, nếu chúng ta nói về ứng dụng của mình, thì tất cả các kiểm tra được chia thành nhiều loại:

  • Phân tích tĩnh: Tôi không biết tại sao cách tiếp cận này lại ít được chú ý đến vậy, nó là một công cụ rất mạnh cho phép bạn áp dụng các quy tắc chính thức cho toàn bộ dự án chứ không phải cho từng lớp riêng lẻ;
  • Kiểm tra đơn vị: các bài kiểm tra đơn vị kiểu cũ tốt để đảm bảo rằng một lớp hoạt động chính xác như những gì nhà phát triển hoặc người dùng lớp đó mong đợi;
  • Kiểm tra giao diện người dùng: các bài kiểm tra chức năng/từ đầu đến cuối để kiểm tra kết quả cuối cùng: người dùng sẽ thấy gì và cách họ sẽ làm việc với nó.

Phân tích tĩnh

Chúng tôi sử dụng các giải pháp làm sẵn làm máy phân tích tĩnh. Đối với Android, đây là Lint, gần đây đã trở thành một công cụ rất hiệu quả để giám sát chất lượng mã, tài nguyên đánh dấu, đồ họa, v.v. dành riêng cho Android. Trong số những thứ khác, nó cho phép bạn thêm các bước kiểm tra theo hợp đồng cụ thể của riêng mình trong một dự án. Một hợp đồng như vậy là không có tham số nào liên quan đến bố cục phải có trong kiểu. Ví dụ: thuộc tính bố cục_margin\layout_alignParentTop hoặc thuộc tính tương tự. Từ quan điểm cú pháp, không ai cấm đưa các thuộc tính này vào kiểu, nhưng trong trường hợp này, bản thân kiểu đó không được sử dụng để xác định thành phần trực quan của một số thành phần UI mà để lưu trữ một số giá trị mà sau đó không cần phải có. được viết trong tập tin đánh dấu. Nói cách khác, kiểu được sử dụng làm nơi chứa các thuộc tính. Chúng tôi đã quyết định rằng đây là những thứ khác nhau cần được tách riêng, bởi vì, thứ nhất, LayoutParams vẫn liên quan đến đánh dấu và thứ hai, chúng không liên quan đến điều khiển mà thẻ mà các thuộc tính này được viết, mà liên quan đến cha mẹ của nó mà anh ta nằm trong đó.

Nếu bạn nhìn vào nó, trong bất kỳ dự án ít nhiều thành công nào đều có hướng dẫn viết mã, tài nguyên đánh dấu và các mẫu để giải quyết các vấn đề điển hình cho ứng dụng này, có khá nhiều thứ như vậy. Chúng có thể được theo dõi ở giai đoạn xem xét mã, ghi lại, nhắc nhở về chúng mọi lúc vào đầu ngày làm việc hoặc bạn có thể tin tưởng vào thực tế rằng, một khi đã quen với những mong muốn này, mọi người sẽ tuân theo chúng trong tương lai. Như người ta nói, phúc thay ai tin tưởng, nhưng cá nhân tôi thấy bình tĩnh hơn nhiều khi làm việc, biết rằng bản thân mình sẽ không quên và không bỏ sót điều gì, vội vã hoàn thành nhanh chóng một nhiệm vụ nhàm chán. Bạn cần chính thức hóa các bước kiểm tra như vậy, thêm chúng vào quá trình xây dựng bằng các báo cáo tiện lợi và đừng lo lắng rằng khi thực hiện một nhiệm vụ mới, bạn sẽ bất ngờ phát hiện ra mã đã bỏ sót tất cả các bước kiểm tra, điều này sẽ khiến bạn dựng tóc gáy.

Việc viết séc của riêng bạn khá dễ dàng, thậm chí còn thú vị. Khi bạn thêm bất kỳ kiểm tra tĩnh nào, một loạt ý tưởng sẽ xuất hiện ngay lập tức về cách xác định tĩnh một số vấn đề khác. Đối với Lint, các hướng dẫn và tài liệu chính thức sẽ trợ giúp việc này. Bạn có thể phát triển các quy tắc trực tiếp trong Android Studio.

Ngoài ra còn có các máy phân tích tĩnh cho mã java được phát minh từ lâu. Tôi sẽ không liệt kê mọi thứ, tôi sẽ chỉ nói với bạn rằng chúng tôi sử dụng FindBugs. Khi chúng tôi chọn một công cụ, chúng tôi muốn có một định dạng thuận tiện, có đủ số lượng quy tắc để thực hiện kiểm tra và khả năng thêm các quy tắc của riêng chúng tôi. Hiện tại, chúng tôi đã viết các bước kiểm tra cần thiết, chẳng hạn như kiểm tra các con trỏ đã đóng, kiểm tra xem phiên bản AccountManager có luôn được lấy cùng với ngữ cảnh ứng dụng hay không, kiểm tra xem phương thức onEventComplete được yêu cầu có được gọi khi sử dụng mẫu của lớp sự kiện và các phương thức khác hay không. Việc thêm các quy tắc của riêng bạn sẽ xác định các thỏa thuận trong nội bộ nhóm và ngăn ngừa các lỗi phổ biến do thiếu chú ý là một phương pháp tuyệt vời giúp giảm thời gian xem xét và kiểm tra mã, đồng thời cũng đảm bảo rằng các lỗi đó ít nhất sẽ không xuất hiện trong phiên bản sản xuất của ứng dụng trong tương lai. Để hướng dẫn viết séc, chúng tôi đã sử dụng bài viết FindBugs, Phần 2: Viết trình phát hiện tùy chỉnh. Nó chỉ rõ cách tạo plugin của riêng bạn, thêm trình phát hiện và sử dụng plugin này trong quá trình xác minh. Báo cáo được cung cấp dưới dạng tài liệu HTML được định dạng hoặc dưới dạng báo cáo XML, trong đó nêu ngắn gọn và nêu rõ lớp/phương thức nào đã tìm thấy lỗi, mã lỗi, dòng, v.v. Điều này thường đủ để hiểu bạn chưa tự dọn dẹp ở đâu :-).

Thật tuyệt vời phải không? Một bộ quy tắc khổng lồ và những lỗi thường gặp đã sẵn sàng, cũng có cơ hội để bổ sung, tất cả những gì bạn phải làm là lấy hết can đảm và bắt đầu sử dụng nó.

Một ngày nọ, tôi nhận thấy rằng dự án của chúng tôi sử dụng các phiên bản thư viện SNAPSHOT. Rõ ràng, điều này chỉ hợp lệ trong một nhánh nhiệm vụ khi những thay đổi này được thực hiện đối với thư viện đang được sử dụng. Sau khi mã được hợp nhất vào nhánh chính, sẽ không có SNAPSHOT trong dự án. Trong trường hợp này, lý do khá tầm thường và đặc trưng cho hầu hết các lỗi này. Sau khi nhiệm vụ được thử nghiệm và quyết định rằng phiên bản này đã đạt được tất cả các định nghĩa đã hoàn thành, nhà phát triển vui mừng đến mức quên gộp thư viện vào nhánh chính, xác định phiên bản mới của thư viện này và thay đổi phiên bản trong nhánh chính. dự án chính. Vấn đề là cả Lint và FindBugs đều không thể kiểm tra tập lệnh xây dựng. Hơn nữa, ngay cả khi những kiểm tra này được thêm vào chính build.gradle, bạn cần biết điều này ở đâu được chấp nhận và nơi nào không. Rõ ràng, điều này có thể chấp nhận được trong một nhánh, trong đó thư viện hiện đang được thay đổi, nhưng không thể chấp nhận được sau khi nó được đưa vào nhánh chung. Đó là cách chúng tôi bắt đầu sử dụng git pre-receive hooks để theo dõi những gì đang xảy ra trong dự án ở cấp kho lưu trữ.

Tôi biết rằng nhiều nhóm không cho rằng cần thiết phải dành thời gian thiết lập các quy tắc phù hợp cho dự án ở cấp hệ thống kiểm soát phiên bản, bởi vì “chúng tôi không phải là kẻ ngốc, sẽ không ai xóa tất cả các nhánh trong kho” hoặc đối với một số nhóm khác lý do lý do, ví dụ như do thiếu thời gian. Đối với chúng tôi, đây là một giai đoạn đã qua: chúng tôi đã đi đến quyết định rằng tốt hơn là nên dành thêm một chút thời gian, nhưng hãy tin tưởng vào sự an toàn và chất lượng của sản phẩm. Móc nhận trước hoạt động rất tốt cho các mục đích sau: chúng tôi có thể phát hiện các thay đổi đang được thêm vào nhánh chia sẻ và kiểm tra xem HEAD của nhánh chia sẻ đó không chứa mã không mong muốn. Trong trường hợp tốt nhất, sẽ không ai biết về sự tồn tại của một tấm séc như vậy, nhưng, như thực tế cho thấy, một sai sót ngẫu nhiên cũng đủ để tạo cơ hội mắc một sai lầm nghiêm trọng. Móc nhận trước hoàn hảo để kiểm tra tất cả TODO và FIXME đã sửa mà nhà phát triển sẵn lòng đặt nhưng lại quên sửa. Nó cũng đối phó tốt với các vấn đề ghi nhật ký điển hình - thêm đầu ra của new Throwable() vào tất cả các chức năng mà nhà phát triển quan tâm, vì một lỗi rất phức tạp đã được tìm thấy trong nhánh yêu cầu nhiều chi tiết. Đối với chúng tôi, khả năng theo dõi những sai lầm đã mắc phải đương nhiên là quan trọng để hiểu rằng chúng tôi sẽ không dẫm lên cùng một vết cào nữa. Mọi người đều mắc sai lầm, điều quan trọng duy nhất là bạn rút ra kết luận gì sau đó. Kết luận của chúng tôi là ngoài việc sửa chữa, cần phải nỗ lực để đảm bảo rằng những sai sót này sẽ không xảy ra trong tương lai.

Kiểm tra đơn vị

Ở đây, nhìn chung, mọi thứ đều bình thường. Đối với một số lớp, các bài kiểm tra được viết để đảm bảo rằng lớp đó hoạt động chính xác như dự kiến, đồng thời hiển thị cho máy khách lớp một ví dụ về cách sử dụng nó. Hiện tại, các bài kiểm tra đơn vị chạy trên thiết bị thực nhưng không thiết lập kết nối thực nếu cần. Nói về sự cần thiết phải thiết lập kết nối: khi một nhà phát triển nghĩ về cách kiểm thử một mô-đun cụ thể, điều đầu tiên anh ta nghĩ đến thường là cách thay thế các phần phụ thuộc của lớp để tách biệt việc kiểm thử khỏi môi trường trực tiếp. Trong trường hợp kết nối mạng, đây có vẻ là một nhiệm vụ khó khăn, vì giao tiếp mạng không được thay thế bằng cách gọi một phương thức duy nhất, nó đòi hỏi phải hack cả một lớp logic. Trong một thời gian, chúng tôi đã phản đối việc sử dụng hook trong mã ứng dụng để ghi đè phản hồi của máy chủ và thực hiện tất cả các hành động tiếp theo với nó. Thực tế là cách tiếp cận này làm tăng nguy cơ mã sẽ được kiểm tra không phải là mã hoạt động trong ứng dụng sản xuất. Mỗi khi câu hỏi được đặt ra liệu có đáng thay đổi giao diện của một lớp để dễ kiểm tra hay không, liệu có đáng thêm các điều kiện bổ sung vào quy trình thực thi hàm để “khóa” một số phần phụ thuộc hay không, tôi cố gắng tuân thủ quan điểm sau : trước hết, tất cả các mã viết phải an toàn về mặt chức năng ứng dụng. Nếu các điều kiện bổ sung được thêm vào mã yêu cầu xác minh riêng thì việc kiểm tra không cần thực hiện việc này. Đây là lý do chính khiến chúng tôi không hài lòng với một công cụ setter thông thường, nó chỉ thay thế câu trả lời, lấy nó từ một nguồn khác.

Kết quả là chúng tôi đã đi đến một quyết định khác, theo tôi, trung thực hơn. Đây là giao diện của một trong các thử nghiệm, kiểm tra xem với một phản hồi nhất định, lệnh có tạo ra trạng thái “error_folder_not_exist” hay không

@AcquireCookie @LargeTest public void testDeleteNonExistingFolder() ( DeleteFolder delete = runDeleteFolder(999); khẳng địnhERROR_FOLDER_NOT_EXIST(delete); )
Trong thử nghiệm này, chúng tôi đưa ra một yêu cầu trung thực tới máy chủ, nghĩa là lệnh hoạt động giống hệt như trong ứng dụng. Vấn đề là việc kiểm tra đơn vị phụ thuộc vào cách cấu hình mạng trên thiết bị mà nó đang chạy. Và dưới đây là bài kiểm tra thứ hai, kiểm tra chính xác điều tương tự, nhưng bằng cách thay thế câu trả lời mong muốn mà không thực hiện yêu cầu thực sự và không tương tác với máy chủ.

@MockMethod(response = RESPONSE_NOT_EXISTS) public void testDeleteNonExistingFolderMock() ( testDeleteNonExistingFolder(); )
Do đó, chúng tôi có cơ hội kiểm soát việc thực hiện các thử nghiệm - chẳng hạn, điều này là cần thiết để trạng thái xây dựng không tính đến phản hồi của máy chủ. Chúng tôi dựa vào thực tế là giao thức tương tác được mô tả và bằng cách đảm bảo rằng yêu cầu được hình thành chính xác (tất nhiên là sử dụng các bài kiểm tra đơn vị), chúng tôi có thể chắc chắn rằng máy chủ sẽ đưa ra phản hồi chính xác. Và nếu câu trả lời là đúng, tất cả những gì còn lại là đảm bảo rằng ứng dụng sẽ diễn giải nó cho phù hợp. Tuy nhiên, ví dụ, đối với bản dựng hàng đêm, sẽ rất tốt nếu đảm bảo rằng hợp đồng tương tác với máy chủ không bị vi phạm. Để làm được điều này, tất cả các thử nghiệm sẽ được triển khai, bao gồm cả những thử nghiệm thực sự tương tác với nó. Điều này sẽ cung cấp cho chúng tôi một mạng lưới an toàn bổ sung trong trường hợp hợp đồng tương tác với máy chủ bị phá vỡ do một số lỗi. Chúng tôi tìm hiểu về điều này từ kết quả thử nghiệm chứ không phải từ đánh giá của người dùng trên thị trường. Nếu việc kiểm tra chức năng từ đầu đến cuối là rất quan trọng đối với chúng tôi thì chúng tôi có thể đặt những thử nghiệm này làm thử nghiệm chính và chạy chúng cho mỗi bản dựng ứng dụng.

Thực tế là chúng tôi không muốn liên tục phụ thuộc vào dịch vụ, nhưng đồng thời chúng tôi cần theo dõi tình hình và nhận thông tin dưới dạng báo cáo hàng ngày rằng mọi thứ đều ổn hoặc một số phần của ứng dụng không hoạt động. đặt hàng. Ở đây, tôi muốn tách ứng dụng của chúng tôi và các dịch vụ của bên thứ ba rất quan trọng cho hoạt động đầy đủ của nó nhưng không phải là lĩnh vực trách nhiệm của chúng tôi. Chúng tôi có thể phát hiện sự cố trong ứng dụng của mình liên quan đến hoạt động của dịch vụ bên thứ ba, nhưng chúng tôi không thể khắc phục sự cố đó. Công việc của chúng tôi là báo cáo sự cố, đợi sự cố được khắc phục và chạy thử nghiệm dịch vụ để đảm bảo sự cố đã được khắc phục.

Kiểm tra giao diện người dùng

Từ quan điểm của người dùng, đây là những bài kiểm tra trung thực nhất. Theo quan điểm của nhà phát triển, chúng là khó khăn nhất. Trung thực nhất vì họ kiểm tra sản phẩm cuối cùng chứ không chỉ một phần của sản phẩm. Đổ lỗi cho người khác sẽ không có tác dụng: bất kỳ lỗi nào cũng là lỗi ứng dụng và không quan trọng nguyên nhân của nó là gì, sự không hoàn hảo của Android nằm trong bàn tay quanh co của nhà phát triển khác hay điều gì khác. Trong mọi trường hợp, lỗi cần phải được sửa chữa. Ưu điểm của thử nghiệm hộp đen như vậy bao gồm thực tế là đối với chúng tôi, trên thực tế, không có gì khác biệt về cách thức triển khai chức năng, kiến ​​trúc của ứng dụng, v.v. Nếu hai lỗi trong ứng dụng trùng lặp với nhau và kết quả là người dùng đã thấy kết quả chính xác - chúng tôi hài lòng với nó. Trong nhiều trường hợp, nếu lỗi ứng dụng cho phép chúng tôi thu được kết quả chính xác cho người dùng thì điều này phù hợp với chúng tôi từ quan điểm kiểm tra chức năng.

Trong khi kiểm thử đơn vị kiểm tra xem mã có hoạt động chính xác như dự định của nhà phát triển hay không, kiểm thử giao diện người dùng được thiết kế nhiều hơn để đảm bảo rằng nhóm sản phẩm đảm bảo rằng tập lệnh của người dùng được thực thi chính xác trong ứng dụng.

Ngoài ra còn có các lỗi liên quan đến tập lệnh của người dùng. Một trong những cách tốt nhất để sửa lỗi ứng dụng khi bạn có tập lệnh để tái tạo nó là viết một bài kiểm thử. Xác minh rằng vấn đề tồn tại. Khắc phục sự cố trong mã ứng dụng (nếu cần, hãy kèm theo các thử nghiệm đơn vị bổ sung trên mô-đun mà mọi hành vi không được đóng) và đảm bảo rằng thử nghiệm hiện đã vượt qua. Trong trường hợp này, không cần thiết phải có sự tham gia của toàn bộ bộ máy quan liêu, trong đó nhiều người phải phê duyệt rằng lỗi đã được sửa, không có gì mới bị hỏng, v.v. Vấn đề cốt lõi là nếu bài kiểm tra được viết một cách chu đáo và chính xác cho Mục đích của việc phát hiện và xác định vấn đề thì nếu hoàn thành thành công thì đã có lý do để coi vấn đề đã được giải quyết. Càng nhiều trường hợp như vậy được kết thúc bằng các cuộc kiểm tra thì chất lượng kiểm tra càng tốt, bởi vì khả năng chúng tôi không bỏ sót điều gì càng cao.

Tất nhiên, làm tất cả những điều này khó hơn nhiều so với việc nói ra. Nhưng điều đầu tiên trước tiên: hãy bắt đầu bằng cách chọn khuôn khổ mà chúng ta sẽ xây dựng các thử nghiệm của mình trên đó. Một lần nữa, tôi sẽ không mở rộng nước Mỹ bằng cách viết rằng hiện nay có khá nhiều khuôn khổ, nhưng không thể chỉ đề xuất một khuôn khổ sẽ giải quyết được 99% mọi vấn đề. Bạn có thể bắt đầu viết khuôn khổ lý tưởng của riêng mình, đặt cược rằng hệ số độ cong bàn tay của bạn nhỏ hơn so với đối thủ cạnh tranh và hy vọng rằng trong một tháng, mọi vấn đề của bạn sẽ được giải quyết và sau sáu tháng, sau khi tính toán chi phí cho giải pháp đó, quay trở lại lựa chọn này một lần nữa. Tôi thực sự không thích làm việc của người khác và có lẽ đó là lý do tại sao tôi nghĩ cách tiếp cận này là không tưởng. Tôi cũng xem thử nghiệm đa nền tảng là một điều không tưởng, vì sự khác biệt giữa Android và iOS là quá lớn. Viết một bộ bài kiểm tra sẽ kiểm tra cả ứng dụng này và ứng dụng khác có vẻ như là một giải pháp rõ ràng ngay từ cái nhìn đầu tiên. Điều hướng khác nhau trong ứng dụng, bố cục khác nhau trong cùng một màn hình, hành vi hệ thống khác nhau để phản ứng với việc thu nhỏ ứng dụng, chưa kể đến thực tế là ngay cả chức năng cũng có thể khác nhau, bởi vì bất kỳ sản phẩm chất lượng cao nào cũng sẽ tính đến tất cả các tính năng của nền tảng nhằm mang đến cho người dùng những trải nghiệm tốt nhất.

Về mặt lịch sử, chúng tôi đã sử dụng Robotium trong dự án. Đây là một giải pháp rất nổi tiếng được nhiều đội trong và ngoài nước sử dụng. Điều thú vị là tất cả người dùng của nó đều có chung một niềm đam mê không thích chính khuôn khổ này. Nó chậm, không ổn định và bất tiện khi viết bài kiểm tra. Nhưng mọi người vẫn thường xuyên quay lại sử dụng nó. Cho dù đó là Espresso! Nó nhanh như gió, ổn định như nền kinh tế Hoa Kỳ, v.v. Đó là điều mà danh tiếng của gã khổng lồ tìm kiếm đã làm cho các dự án mà nó đảm nhận. Chúng tôi đã viết về Robotium được 2 năm, vì vậy tôi có thể khá tự tin nói rằng trách nhiệm về sự không ổn định và tốc độ thấp nằm ở khách hàng viết những bài kiểm tra này. Hãy tìm hiểu điều này. Nguyên nhân của các vấn đề về tốc độ thường không nằm ở sự không hoàn hảo của thuật toán Robotium, cũng không phải ở kiến ​​trúc của nó, mà nằm ở thực tế là các bài kiểm tra có lạm dụng cái gọi là Mô hình ngủ. Bản chất của nó là mọi vấn đề đều có thể được giải quyết bằng cách thêm sleep(N * 1000) trước dòng phát hiện ra vấn đề. Cơ sở của điều này là điều đơn giản sau: các bài kiểm tra được thực thi trong một luồng khác với luồng ứng dụng chính (UI Thread). Theo đó, việc đồng bộ hóa được thực hiện bằng Sleep() không phải là giải pháp tốt cho vấn đề. Do đó, kết quả là: ngay cả khi bạn đợi 10 giây giữa các bước trong quá trình kiểm tra, kết quả sẽ không được đảm bảo. Trong các thử nghiệm dựa trên Thiết bị đo, có một thứ đang chờ Chuỗi giao diện người dùng của ứng dụng hoàn tất các hoạt động hiện đang được tiến hành. Lớp android.app.Instrumentation có một phương thức:

/** * Đồng bộ đợi ứng dụng ở trạng thái rảnh. Không thể gọi * từ luồng ứng dụng chính -- sử dụng (@link #start) để thực thi * công cụ đo lường trong luồng riêng của nó. */ public void waitForIdleSync() ( validNotAppThread(); Idler Idler = new Idler(null); mMessageQueue.addIdleHandler(idler); mThread.getHandler().post(new EmptyRunnable()); idler.waitForIdle(); )
Việc sử dụng nó, như chúng tôi đã trải nghiệm, sẽ giải quyết được hầu hết các vấn đề với việc không tìm thấy Chế độ xem, mặc dù ảnh chụp màn hình cho thấy mọi thứ đều được hiển thị, cũng như Chế độ xem ở trạng thái trung gian, tạo hiệu ứng động cho các thuộc tính của nó từ giá trị này sang giá trị khác, v.v.

Đương nhiên, những câu chuyện về việc Espresso ngon hơn gấp nhiều lần đã ám ảnh chúng ta. Kế hoạch chuyển sang khuôn khổ này đã chín muồi từ lâu; Ngoài ra, hiện nay Google cũng đang dành khá nhiều sự quan tâm đến vấn đề thử nghiệm tự động nên có những điều kiện tiên quyết để Espresso sẽ phát triển tích cực hơn. Quyết tâm này còn được tăng thêm bởi niềm tin của Trưởng nhóm phát triển rằng việc chuyển từ Robotium sang Espresso chỉ cần thay đổi TestRunner là đủ. Chúng tôi đã thử nó và các bài kiểm tra thực sự có hiệu quả. Bây giờ chúng ta có thể viết các tập lệnh mới mà không cần thay đổi các bài kiểm thử cũ tại một thời điểm mà vẫn tận dụng được tất cả lợi ích của Espresso. Đối với chúng tôi, điều này quyết định việc chuyển đổi sang một khuôn khổ mới. Chúng tôi bắt đầu thử nghiệm và đứng ngồi chờ kết quả.

Espresso thực sự nhanh hơn, mặc dù không có thay đổi đáng kể nào. Bây giờ tất cả các thử nghiệm của chúng tôi được chia thành ~ 26 gói và tốc độ tăng tốc đã được nhận thấy trong mỗi gói. Nhưng tổng số thay đổi về tốc độ vượt qua các bài kiểm tra nằm trong khoảng 4%. Theo tôi, đây không phải là một lợi thế đáng kể. Theo quan điểm của tôi, còn nhiều hơn thế nữa, cho phép viết một bản tương tự của WaitForIdleSync cho bất kỳ sự chờ đợi nào trong ứng dụng: không chỉ cho các tác vụ giao diện và hoạt ảnh mà còn cho các tác vụ tải dữ liệu từ mạng và từ đĩa - cho mọi tương tác kết quả mà chúng ta phải thực hiện bằng cách kiểm tra mã kiểm tra. Tính năng này được gọi là CustomIdlingResource và nó thực sự khiến Espresso nổi bật so với Robotium. Mặc dù thực tế là ý tưởng rất đơn giản, cụ thể là để cung cấp cơ hội đăng ký triển khai giao diện chờ ở trạng thái không hoạt động của riêng bạn, tài nguyên không hoạt động tùy chỉnh cho phép bạn quản lý đồng bộ hóa giữa các thử nghiệm và ứng dụng. Bằng cách này, bạn có thể đợi cho đến khi tất cả các hoạt động không đồng bộ hoàn tất trong ứng dụng, chẳng hạn, cùng với trạng thái không hoạt động của luồng chính, cho biết rằng thời gian chờ có thể được hoàn thành và việc kiểm tra trạng thái ứng dụng có thể bắt đầu.

Đương nhiên, Espresso không phải là thần tiên. Nó không thể giải quyết tất cả các vấn đề của bạn, nó không thể viết bài kiểm tra cho bạn và nó không thể xử lý các nhiệm vụ duy trì cơ sở hạ tầng kiểm tra, chạy thử nghiệm và thu thập báo cáo.

Ngoài việc kiểm tra chức năng thực tế trong ứng dụng, một thách thức chung gặp phải trong bối cảnh kiểm tra chất lượng tự động là cách sản phẩm của bạn tương tác với các ứng dụng khác có thể được cài đặt trên điện thoại của người dùng. Ví dụ: bạn có thể lấy Chia sẻ từ một ứng dụng khác (điều này khá phù hợp với ứng dụng email) hoặc thanh trạng thái của thông báo. Trong cả hai trường hợp, tập lệnh đều ảnh hưởng đến một ứng dụng khác đang chạy trong một quy trình khác. Tất cả các khung giống như Robotium/Espresso đều trở nên mù mịt ngay khi có một quy trình khác tham gia. May mắn thay, đã tồn tại một giải pháp cho phép bạn viết các bài kiểm tra giao diện người dùng chức năng trên nhiều ứng dụng và được gọi là UI Automator. Nếu trước đây chúng tôi phải lựa chọn giữa khung này hay khung khác hoặc hỗ trợ các dự án khác nhau, mỗi dự án sẽ được điều chỉnh cho các bước kiểm tra khác nhau, thì với việc phát hành Thư viện hỗ trợ kiểm tra, được công bố tại hội nghị Google I/O 2015 vừa qua, chúng tôi có thể kết hợp các ưu điểm của từng phương pháp và sử dụng các công cụ cần thiết trong từng trường hợp riêng lẻ. Điều này có nghĩa là đối với một ứng dụng email chẳng hạn, chúng tôi có thể tự động hóa tập lệnh sau:

  1. Khởi chạy ứng dụng, vào danh sách các chữ cái.
  2. Mở soạn thư mới, nhập chủ đề, người nhận, đính kèm file đính kèm.
  3. Nhận thông báo đẩy tới hộp thư được kết nối của bạn.
  4. Vào thông báo và kiểm tra nội dung thư mới.
  5. Thoát khỏi màn hình viết thư mới bằng nút quay lại. Đảm bảo rằng chúng ta đã quay lại màn hình viết thư và tất cả các trường đã hoàn thành đều được lưu.
Trong ví dụ này, chúng ta có thể sử dụng khung trước đó một cách an toàn để di chuyển qua các mô hình danh sách các chữ cái, đọc một lá thư, viết một lá thư mới, v.v. và đối với bước 3 và 4, chúng ta có thể sử dụng khung uiAutomator để kiểm tra thông báo văn bản, hãy đảm bảo rằng thông báo chứa các nút cần thiết và làm theo thông báo để đến ứng dụng. Sau đó, thử nghiệm sẽ tiếp tục sử dụng API Espresso và chúng tôi sẽ không phải viết một triển khai khác cho các mô hình hiện có cho khung thứ hai. Đối với tôi với tư cách là một nhà phát triển, đây là tin tốt nhất có thể xuất hiện trong bối cảnh các thư viện tự động hóa thử nghiệm.

Tất nhiên, tất cả điều này thoạt nhìn có vẻ đơn giản. Đằng sau hậu trường là một đống cào được thu thập và bước vào những chất khó chịu nhất - đôi khi dường như toàn bộ ý tưởng này đơn giản là không thể thực hiện được.

Trong tương lai, chúng ta sẽ nói riêng về cách xây dựng cơ sở hạ tầng, cách đảm bảo các thiết bị sẵn sàng hoạt động suốt ngày đêm, cách phân phối các thử nghiệm cho các hương vị sản phẩm khác nhau trên các tổ hợp khác nhau, cách thử nghiệm các triển khai khác nhau tùy thuộc vào phiên bản của hệ điều hành, kiểu dáng thiết bị, v.v. Suy cho cùng, chúng tôi đã có hai năm dài vật lộn với adb, usb, VirtualBox cũng như nhiều công cụ và công nghệ khác. Còn nhiều việc phải làm ở phía trước hơn những gì đã làm, nhưng chúng tôi hiểu rằng tất cả những điều này không phải là vô ích.

Chúng tôi khuyên bạn nên mua khóa học này hoàn chỉnh cùng với khóa học “Phát triển ứng dụng di động trên 1C 8.3”.

Trong khóa học thứ hai, chúng tôi xem xét chi tiết cách kiếm tiền từ các ứng dụng di động, cũng như những điều bạn cần tính đến trước khi phát triển chúng.

Khả năng thêm khóa học thứ hai vào giỏ hàng của bạn sẽ xuất hiện trong biểu mẫu để nhập đơn hàng - sau khi bạn nhấp vào nút “Đặt hàng!”.

Bảo đảm

Chúng tôi đã giảng dạy từ năm 2008, chúng tôi tự tin vào chất lượng các khóa học của mình và cống hiến hết mình bảo hành 60 ngày tiêu chuẩn.

Điều này có nghĩa là nếu bạn bắt đầu tham gia khóa học của chúng tôi nhưng đột nhiên thay đổi ý định (hoặc nói rằng không có cơ hội), thì bạn có thời hạn 60 ngày để đưa ra quyết định - và nếu bạn quay lại, chúng tôi sẽ trả lại 100 % số tiền thanh toán.

Trả góp

Các khóa học của chúng tôi có thể được thanh toán theo đợt hoặc trả góp, kể cả không tính lãi. trong đó Bạn có quyền truy cập ngay vào tài liệu.

Điều này có thể thực hiện được với các khoản thanh toán từ các cá nhân với số tiền từ 3.000 RUB trở lên. lên tới 150.000 chà.

Tất cả những gì bạn cần làm là chọn phương thức thanh toán “Thanh toán qua Yandex.Checkout”. Tiếp theo, trên trang web của hệ thống thanh toán, hãy chọn “Thanh toán theo đợt”, cho biết thời hạn và số tiền thanh toán, điền vào biểu mẫu ngắn - và sau vài phút, bạn sẽ nhận được quyết định.

Các lựa chọn thanh toán

Chúng tôi chấp nhận tất cả các hình thức thanh toán chính.

Từ cá nhân– thanh toán từ thẻ, thanh toán bằng tiền điện tử (WebMoney, YandexMoney), thanh toán qua ngân hàng Internet, thanh toán qua các cửa hàng truyền thông, v.v. Cũng có thể thanh toán đơn hàng theo đợt (trả góp), bao gồm cả việc không tính thêm lãi.

Bắt đầu đặt hàng - và ở bước thứ hai, bạn có thể chọn phương thức thanh toán ưa thích của mình.

Từ các tổ chức và cá nhân doanh nhân– Thanh toán không dùng tiền mặt, cung cấp chứng từ giao hàng. Bạn nhập đơn hàng và có thể in ngay hóa đơn để thanh toán.

Đào tạo một số nhân viên

Các khóa học của chúng tôi được thiết kế cho việc học tập cá nhân. Đào tạo nhóm trên một bộ là phân phối bất hợp pháp.

Nếu một công ty cần đào tạo nhiều nhân viên, chúng tôi thường cung cấp “bộ dụng cụ bổ sung” với chi phí thấp hơn 40%.

Để đặt hàng một “bộ bổ sung” chọn 2 bộ khóa học trở lên trong biểu mẫu, bắt đầu từ tập thứ hai chi phí của khóa học sẽ rẻ hơn 40%.

Có ba điều kiện để sử dụng bộ dụng cụ bổ sung:

  • Bạn không thể chỉ mua một bộ bổ sung nếu ít nhất một bộ thông thường chưa được mua trước đó (hoặc cùng với nó)
  • Không có giảm giá nào khác cho các bộ bổ sung (chúng đã được giảm giá, đó sẽ là “giảm giá trên giảm giá”)
  • chương trình khuyến mãi không có giá trị cho các bộ bổ sung (ví dụ: khoản bồi thường 7.000 rúp) vì lý do tương tự

Phát triển ứng dụng di động luôn gắn liền với nhu cầu học hỏi thêm các công nghệ. Điều gì sẽ xảy ra nếu chúng ta xem xét lại câu hỏi và sử dụng các công cụ quen thuộc?

Lần đầu tiên công ty 1C cố gắng thâm nhập thị trường phát triển di động vào năm 2006. Vào thời điểm đó, người ta thực sự đang gấp rút tự động hóa công việc của nhân viên từ xa bằng PDA. Các chương trình mới để giải quyết những vấn đề như vậy xuất hiện như nấm và một nhà cung cấp như 1C với các sản phẩm thành công trong việc tự động hóa các lĩnh vực kinh doanh khác nhau không thể bỏ lỡ cơ hội thâm nhập một thị trường có lợi nhuận.

Đến giữa năm 2006, công ty giới thiệu việc phát hành một sản phẩm mới với cái tên đầy hứa hẹn “1C: Enterprise 8. Phần mở rộng cho máy tính bỏ túi”. Các nhà phát triển 1C, những người nhìn thấy triển vọng của nền tảng thứ 8, bắt đầu hy vọng rằng giờ đây, bằng cách sử dụng một công cụ, việc phát triển cho hệ điều hành di động “Windows Mobile”, vốn phổ biến trong những năm đó, trở nên dễ dàng.

Trong thực tế, mọi thứ trông tồi tệ hơn nhiều. Công cụ này không cho phép chúng tôi thực hiện những ý tưởng ban đầu. Túi nhựa" Tiện ích mở rộng cho máy tính cầm tay» giống một tiện ích bổ sung dành cho một số cấu hình điển hình nhất định hơn là một giải pháp phát triển chính thức. Không có điều khoản nào để mở rộng chức năng cấu hình bằng cách thêm các đối tượng siêu dữ liệu mới. Những việc rất đơn giản được giao cho các lập trình viên bên thứ ba: tạo các biểu mẫu mới để tương tác với người dùng, xử lý các sự kiện của người dùng.

Đúng, có đủ loại cách giải quyết cho những hạn chế, nhưng thậm chí chúng còn không cho phép sự phát triển thực sự. Ngoài những hạn chế về mặt kỹ thuật, người tiêu dùng còn cảm thấy rào cản tài chính nghiêm trọng. Các công ty quyết định triển khai giải pháp từ 1C được yêu cầu mua các PDA hiệu quả, mua giấy phép cho Windows Mobile và cũng phải trả 1C cho việc phân phối giải pháp và ứng dụng cuối cùng.

Giải pháp từ 1C quá đắt. Các công ty đã quen với việc tiết kiệm tiền tiếp tục sử dụng các giải pháp thay thế. Hơn nữa, các nhà phát triển giải pháp thay thế đã cố gắng trang bị cho sản phẩm của họ chức năng tương tác với các giải pháp 1C tiêu chuẩn.

Những hạn chế về kỹ thuật và giá thành cao đã không cho phép sản phẩm lặp lại thành công vang dội của nền tảng máy tính để bàn. Ý tưởng chinh phục thị trường di động của tòa nhà.

các ứng dụng thất bại thảm hại.

Bước về phía trước

Những mất mát và thua lỗ từ một dự án không thành công không đặt dấu chấm hết cho sự phát triển của một hướng đi đầy hứa hẹn. Năm 2013, công ty 1C đã giới thiệu phiên bản ổn định đầu tiên của nền tảng mới 8.3, có chức năng phát triển ứng dụng di động.

1C đã suy nghĩ lại hoàn toàn cách tiếp cận của mình để giải “định lý” di động và tính đến những sai sót của sản phẩm không thành công trước đó. Kết quả là một công cụ hoàn toàn mới không có điểm chung với người tiền nhiệm và tập trung vào các nền tảng di động mới nhất - Android và iOS.

Ứng dụng di động theo phong cách 1C

Để làm quen hoàn toàn với khả năng phát triển của nền tảng di động, chúng tôi sẽ cố gắng phát triển một cấu hình nhỏ. Bằng cách sử dụng ví dụ toàn diện, bạn có thể đánh giá tốt hơn chức năng sẵn có và quyết định khả năng sử dụng nền tảng 1C để giải quyết vấn đề.

Để hoạt động, bạn cần có bản phát hành mới nhất của nền tảng 1C:Enterprise 8.3. Phiên bản giáo dục của bản phân phối có sẵn trên trang web chính thức của 1C. Có quá đủ để tạo lại một ví dụ về khả năng của nó.

Ngoài nền tảng 1C:Enterprise 8.3, chúng tôi sẽ cần một số công cụ bổ sung. Bài viết này sẽ xem xét một ví dụ về phát triển ứng dụng Android. Về vấn đề này, bạn sẽ phải tải xuống: Android SDK và máy chủ WEB Apache. Thành phần đầu tiên chứa mọi thứ cần thiết để xây dựng ứng dụng và trình mô phỏng để thử nghiệm, đồng thời máy chủ WEB rất hữu ích để nhanh chóng tải ứng dụng xuống hệ điều hành di động.

Chúng tôi cũng sẽ yêu cầu cung cấp “Nền tảng dành cho nhà phát triển di động”. Nó chứa cấu hình để đơn giản hóa quá trình xây dựng ứng dụng di động đã tạo cũng như nền tảng dành cho nhà phát triển di động. Nó phải được cài đặt trên thiết bị di động hoặc trình giả lập.

Để xây dựng một ứng dụng sẵn sàng phân phối qua Google Play, bạn sẽ cần tải xuống người ApacheJavaJDK. Chủ đề này nằm ngoài phạm vi của bài viết này, vì vậy bạn có thể tìm hiểu thêm về cách làm việc với các công cụ này và lắp ráp ứng dụng trong phần tương ứng của .

Công cụ cấu hình

Nền tảng " 1C:Doanh nghiệp 8.3" và máy chủ web Apache được cung cấp các trình cài đặt và được cài đặt theo cách tiêu chuẩn. SDK Android bạn chỉ cần giải nén nó vào một thư mục riêng và chạy “ quản lý sdk.exe" Một cửa sổ sẽ xuất hiện trước mặt bạn với tuyển chọn các gói có sẵn để cài đặt. Để kiểm tra ví dụ được thảo luận trong bài viết này, bạn sẽ cần chọn và cài đặt: Công cụ SDK Android, MỘT Công cụ nền tảng ndroid, API nền tảng SDK 17.

Bước cuối cùng sẽ là tạo ra một cơ sở thông tin mới. Dành cho những người không tham gia phát triển theo " 1C:Doanh nghiệp“Tôi sẽ giải thích rằng mọi giải pháp cho nền tảng này đều bao gồm cơ sở thông tin và cấu hình. Việc thêm cơ sở dữ liệu mới được thực hiện bằng cách nhấp vào " Thêm vào» cửa sổ bắt đầu. Sau khi thêm cơ sở dữ liệu, hãy mở nó trong " Bộ cấu hình».

Cấu hình di động đầu tiên

Trong menu chính của bộ cấu hình, chúng ta sẽ tìm thấy phần “ Cấu hình" và chọn "Mở cấu hình". Cây cấu hình (các đối tượng sẽ tạo nên ứng dụng trong tương lai) sẽ được hiển thị ở phía bên trái của cửa sổ. Chọn root cấu hình trong đó rồi nhấn tổ hợp phím “ Alt+Enter" Trình chỉnh sửa thuộc tính sẽ mở ở phần bên phải của cửa sổ cấu hình.

Hãy gọi cấu hình " LÀM" và trong thuộc tính "Mục đích sử dụng" chúng tôi chỉ ra " Thiết bị di động" Xin lưu ý rằng sau khi thực hiện hành động cuối cùng, một số nút của cây cấu hình sẽ không hoạt động. Thật không may, không thể sử dụng tất cả các đối tượng siêu dữ liệu trên nền tảng di động.

Để giải quyết vấn đề của chúng tôi, chúng tôi sẽ cần tạo một số đối tượng siêu dữ liệu trong cây cấu hình:


Quy trình AddTask(Task) XuấtRecordManager = CreateRecordManager(); RecordManager.Period = CurrentDate(); RecordManager.Task = Nhiệm vụ; RecordManager.Status = Nhiệm vụ.Status; RecordManager.Record(); Kết thúcThủ tục

Liệt kê 2. Mã của hàm “Lấy danh sách các nhiệm vụ chưa được tiết lộ()”

Hàm GetList của UnClosedTasks() Yêu cầu xuất = Yêu cầu mới; Query.Text = "SELECT |TaskStatusSliceLast.Task AS Nhiệm vụ, |TaskStatusSliceLast.Task.ExecutionDate AS ExecutionDate |FROM | Đăng ký thông tin.TaskStatus.SliceLast(&CurrentDate, Status<>VALUE(Enumeration.TaskStatuses.Completed)) AS StateTasksSliceLast | | ĐẶT HÀNG BỞI | Ngày thực hiện DESC"; request.SetParameter("CurrentDate", CurrentDate()); Trả về yêu cầu.Execute().Unload(); EndFunction

Chúng ta đã sắp xếp việc lấy dữ liệu từ sổ đăng ký thông tin và ghi lại nó, bây giờ hãy hướng dẫn thư mục của chúng ta cách làm việc với sổ đăng ký. Để thực hiện việc này, hãy thêm một mô-đun chung vào cây cấu hình có tên “ Làm việc với các tác vụ" Bạn có thể làm mà không cần nó, nhưng tôi muốn tập trung ngay vào khả năng chia mã thành các mô-đun. Nhiều nhà phát triển 1C vẫn bỏ qua khuyến nghị này và mô tả tất cả logic ở một nơi, do đó làm phức tạp thêm việc bảo trì mã tiếp theo. Hãy tạo một thủ tục mới trong mô-đun " Tạo nhiệm vụ mới"(xem Liệt kê 3).

Liệt kê 3. Mã cho thủ tục “Tạo tác vụ mới”

Quy trình CreateNewTask(Link) Xuất Nếu Link.ThisGroup Sau đó Return; endIf; Yêu cầu = Yêu cầu mới; Query.Text = "SELECT |TaskStatusSliceLast.Status |FROM |Đăng ký thông tin.TaskStatus.SliceLast(&CurrentDate, Task = &Task) AS TaskStatusSliceLast"; Query.SetParameter("CurrentDate", CurrentDate()); Yêu cầu.SetParameter("Nhiệm vụ", Liên kết); Kết quả = Query.Run().Select(); Nếu Result.Next() Thì Nếu Result.Status<>Link.Status Sau đó Thông tin Registers.Task Status.AddTask(Link); endIf; Ngược lại, thông tin Registers.TaskStatus.AddTask(Link); endIf; Kết thúcThủ tục

Trước khi tạo bản ghi mới, việc kiểm tra sự hiện diện của các bản ghi hiện có cho nhiệm vụ được thực hiện. Nếu bản ghi đã tồn tại thì bạn cần so sánh trạng thái nhiệm vụ. Nếu trạng thái từ thanh ghi không khác với trạng thái của phần tử được ghi thì không cần tạo mục nhập bổ sung.

Để hoàn thiện, hãy mở biểu mẫu của mục thư mục “Nhiệm vụ” và tạo trình xử lý sự kiện “ Sau khi ghi trên máy chủ" Trong đó chúng ta sẽ gọi thủ tục được mô tả trong danh sách thứ ba:

WorkWithTasks.CreateNewTask(CurrentObject.Link);

Chúng tôi đang làm việc trên giao diện

Chức năng chính của ứng dụng đã sẵn sàng - người dùng có thể tạo các tác vụ và mỗi tác vụ mới sẽ tạo một mục trong sổ đăng ký thông tin định kỳ. Bây giờ chúng ta chuyển sang giao diện. Hãy đặt công việc và nhiệm vụ lên hàng đầu. Chắc chắn sẽ hợp lý khi hiển thị ngay danh sách các tác vụ chưa được tiết lộ và khả năng tạo một tác vụ mới ngay sau khi khởi chạy ứng dụng?

Hãy tìm nút " Các biểu mẫu chung" và thêm một biểu mẫu mới tên là " Máy tính để bàn" Hãy mở biểu mẫu đã tạo trong trình thiết kế giao diện và thêm thuộc tính như " Bảng giá trị" Hãy gọi nó là “OpenZachi”. Bảng sẽ chứa hai cột - " Nhiệm vụ"(Liên kết tham khảo.Tác vụ) và " Ngày thi hành" (Ngày của).

Bước tiếp theo là kéo các đạo cụ đã thêm vào biểu mẫu. Chúng ta nên có một giao diện cho một bảng đơn giản. Chúng tôi sẽ không chỉ định bất kỳ kích thước nào; chúng tôi sẽ không phải lo lắng về việc mở rộng giao diện cho nền tảng.

Đối với bảng đã tạo, trong trình kiểm tra thuộc tính, hãy đặt hộp kiểm cho thuộc tính " Chỉ xem", và thuộc tính" Vị trí bảng lệnh» đặt giá trị thành “Không”. Chúng tôi sẽ điền thông tin động vào bảng để người dùng không cần chỉnh sửa.

Bây giờ hãy mô tả trình xử lý sự kiện “Khi CreatedOnServer” cho biểu mẫu. Hãy thêm một dòng mã vào nó:

OpenTasks.Load(InformationRegisters.TaskStatus.GetListofUnClosedTasks());

Trong mã, chúng tôi đề cập đến quy trình mà chúng tôi đã mô tả " Lấy danh sách nhiệm vụ chưa được tiết lộ" và kết quả thực hiện của nó được đặt trong bảng.

Hãy quay lại trình thiết kế biểu mẫu và thêm một nhóm loại “Nhóm thông thường không hiển thị” bằng hai nút: “ Tạo nên" Và " Cập nhật" Tài sản " Nhóm"Đối với nhóm đã thêm, đặt giá trị thành"Ngang". Để làm cho các nút biểu cảm hơn, hãy thêm hình ảnh và thay đổi phông chữ mặc định.

Bây giờ hãy chọn nút " Tạo nên" và đưa cho nó lệnh toàn cục " Nhiệm vụ: tạo" Điều này sẽ cho phép bạn tạo các tác vụ mà không cần vào chính thư mục đó. Bằng cách nhấp vào nút thứ hai, chúng tôi sẽ cập nhật nội dung của bảng với các tác vụ. Để thực hiện việc này, bạn sẽ cần tạo một lệnh biểu mẫu bổ sung.

Tất cả các lệnh biểu mẫu mới được tạo trên tab cùng tên " Đội" Nguyên tắc rất đơn giản - chúng tôi thêm một lệnh mới, mô tả mã hành động trong đó và sau đó liên kết lệnh đó với giao diện, trong trường hợp của chúng tôi là với nút.

Chúng ta cũng không nên quên rằng chúng ta đang phát triển một ứng dụng được quản lý nên cần phân biệt rõ ràng giữa mã máy khách và mã máy chủ. Khi nhấp vào nút sẽ có ngữ cảnh " OnClient", và chúng ta sẽ nhận được dữ liệu từ cơ sở dữ liệu từ máy chủ. Trong mã nó trông như thế này:

&Trên Thủ tục Khách hàng UpdateTaskList(Command) UpdateList(); Kết thúc quy trình &Trên quy trình máy chủ khi được tạo trên máy chủ (Lỗi, xử lý tiêu chuẩn) OpenTasks.Load(InformationRegisters.TaskStatus.GetListofUnClosedTasks()); Kết thúcThủ tục

Bây giờ hãy xác định biểu mẫu trên màn hình của chúng ta là khu vực trang chủ. Mở thuộc tính cấu hình (chọn nút trên cùng và nhấp vào “ Alt+Enter") và đối với thuộc tính "Khu vực làm việc của trang chủ" đặt giá trị " Một cột", sau đó thêm biểu mẫu của chúng tôi vào danh sách" Máy tính để bàn».

Ứng dụng đã hoàn toàn sẵn sàng và đã đến lúc thử nghiệm nó trong thực tế. Hãy thử chạy ví dụ này và tạo một số tác vụ có trạng thái khác " Hoàn thành" Sổ đăng ký thông tin đã được bổ sung các mục mới (có thể xem thông tin này thông qua mục menu “ Tất cả các chức năng") và một số trong số chúng được hiển thị trên màn hình nền.

Hạ cánh trên Android

Cấu hình hoạt động tốt trên máy tính để bàn và bây giờ là lúc để thử nghiệm nó trên trình giả lập hệ điều hành di động. Để chuẩn bị trình mô phỏng mới, hãy chạy trình thông dịch lệnh ( cmd.exe) và đi tới thư mục “toos” của bản phân phối SDK Android. Chạy lệnh " android.bat avd", thao tác này sẽ khởi chạy trình quản lý thiết bị Android ảo. Trong đó, nhấp vào nút "Tạo" và trong cửa sổ xuất hiện, chỉ định các tham số của thiết bị ảo. Trong môi trường làm việc của mình, tôi quyết định noi gương Nexus S với Android phiên bản 4.2.2. (API cấp 17).

Sau khi tạo thiết bị, chúng ta sẽ khởi chạy nó ngay lập tức. Trong khi Android đang tải, hãy quay lại trình cấu hình và xuất bản ứng dụng của chúng tôi trên máy chủ web. Trong menu chính của bộ cấu hình, chọn mục “ Cấu hình» -> « Ứng dụng di động» -> « Công bố" Trong cửa sổ cài đặt xuất bản, chúng tôi chỉ định tên của ứng dụng (có thể là bất kỳ thứ gì), máy chủ web (trong môi trường của chúng tôi phải có một) và thư mục để lưu trữ cài đặt.

Chỉ định như tên " việc cần làm trên di động", ứng dụng sẽ có tại địa chỉ - " http://host/todo-mobile" Nhấp vào “ok” và thử truy cập ứng dụng đã xuất bản bằng trình duyệt. Nếu thành công, máy chủ sẽ trả về mã XML của cấu hình đã tạo.

Hãy quay lại trình mô phỏng và tải ứng dụng có nền tảng dành cho nhà phát triển di động vào đó. Bản thân tệp ứng dụng có sẵn cùng với việc phân phối nền tảng dành cho nhà phát triển di động và được gọi là “1cem-arm.apk”. Để cài đặt ứng dụng này trong trình giả lập, chúng ta sẽ sử dụng tiện ích “ adb.exe"từ thư mục" công cụ nền tảng»: cài đặt adb.exe –r 1cem-arm.apk.

Sau khi cài đặt thành công, hãy mở danh sách ứng dụng trong trình giả lập và khởi chạy nền tảng dành cho nhà phát triển di động. Trong cửa sổ mở ra, nhấp vào “ Thêm ứng dụng" và trong trường "địa chỉ", chúng tôi chỉ ra URL tới máy chủ web của chúng tôi. Tôi có cái này http://192.0.168.106/todo-mobile. Nhấp chuột " Thêm vào"và cấu hình của chúng tôi đã được chuyển thành công sang nền tảng di động. Ứng dụng đã sẵn sàng để sử dụng. Kiểm tra kết quả và quay lại bộ cấu hình, đã đến lúc cung cấp “chức năng di động” cho các ứng dụng.

Gửi tin nhắn SMS/MMS

Các chức năng làm việc với SMS/MMS nhắn tin được hỗ trợ khác nhau bởi các nền tảng di động. Ví dụ: khi chạy một ứng dụng trên Android, nhà phát triển có cơ hội đăng ký SMS và có quyền truy cập vào tin nhắn mới ngay sau khi nhận được chúng. Thật không may, tính năng tương tự này không có sẵn trên iOS, vì vậy cần có sẵn tài liệu trong quá trình phát triển.

Một đối tượng được cung cấp để gửi tin nhắn SMS tin nhắn SMStin nhắn. Hãy xem một ví dụ:

&Thủ tục OnClient SendSMSMessage(Người nhận, MessageText) NewMessage = SMSMessage mới(); NewMessage.Text = MessageText; NewMessage.Recipients.Add(Người nhận); Công cụ điện thoại.SendSMS(NewMessage); Kết thúcThủ tục

Mã này khá đơn giản và hầu như không cần bình luận. Bây giờ hãy xem việc đăng ký nhận tin nhắn đến:

&Trên quy trình khách hàng ConnectMessageReceiveHandler() Đăng kýToMessages = New AlertDescription("ProcessingNewMessages", ThisObject); Công cụ điện thoại.ConnectSMSMessageHandler(SubscribeToMessages); Kết thúc thủ tục &Về thủ tục khách hàng Đang xử lý tin nhắn mới (Tin nhắn, thông số bổ sung) // Đang xử lý tin nhắn mới // Người gửi, Tin nhắn; Kết thúcThủ tục

Thủ tục " Xử lý tin nhắn mới" sẽ được gọi mỗi khi nhận được SMS mới. Thông qua tham số " Tin nhắn" một đối tượng thuộc loại " được truyền đi tin nhắn SMStin nhắn» và chúng tôi có thể dễ dàng lấy được nội dung của tin nhắn cũng như thông tin về người gửi.

Làm việc với tin nhắn MMS được thực hiện theo cách tương tự. Đầu tiên, chúng tôi tạo một tin nhắn SMS và sau đó chúng tôi thêm tệp đính kèm (ví dụ: hình ảnh) vào đó. Với hành động đơn giản này, SMS sẽ biến thành MMS:

NewMessage= SMSMessage mới(); Tệp đính kèm = Tệp đính kèm MMS mới; Attachment.Data = Hình ảnh; Attachment.ContentType = "hình ảnh/jpeg"; MMSMessage.Attachments.Add(Đính kèm);

Thực hiện cuộc gọi từ ứng dụng di động

Một cuộc gọi theo chương trình được thực hiện bằng phương pháp “Quay số” của đối tượng chung “Công cụ điện thoại”. Trước khi gọi phương thức, bạn nên kiểm tra khả năng thực hiện cuộc gọi:

Nếu Telephony Tools.SupportedDialing() thì Telephony Tools.DialNumber(PhoneNumber, CallImmediately); endIf;

Tham số " Gọi ngay» ảnh hưởng đến hiệu suất quay số. Khi nó bằng " ĐÚNG VẬY", việc quay số được thực hiện tự động thông qua ứng dụng gọi điện tiêu chuẩn. Nếu được đặt thành Sai, người dùng cũng sẽ thấy giao diện quay số tiêu chuẩn nhưng sẽ cần nhấn nút " để thực hiện cuộc gọi Gọi».

Nhật ký cuộc gọi

Nền tảng di động cho phép nhà phát triển tương tác với nhật ký cuộc gọi. Ví dụ: bạn có thể dễ dàng nhận được danh sách các cuộc gọi đi, cuộc gọi nhỡ hoặc cuộc gọi đến. Tính năng này chỉ được hỗ trợ trên Android:

Nhật ký cuộc gọi = Công cụ điện thoại.GetCall Log(); Lựa chọn = NewDataCompositionSelection; Phần tử lựa chọn = Selection.Elements.Add(Type("DataCompositionSelection Element")); SelectionElement.LeftValue = NewDataCompositionField("CallType"); SelectionElement.ComparisonView = So sánhTypeDataLayout.Equals; SelectionElement.RightValue = CallLogCallType.Missed; SelectionElement.Use = True; Danh sách các mục nhập Nhật ký cuộc gọi = CallLog.FindRecords(Selection); // Danh sách các mục nhật ký cuộc gọi sẽ chứa một tập hợp các mục

Định vị địa lý

Hầu hết mọi điện thoại thông minh hiện đại đều có chức năng định vị địa lý. Bạn có thể sử dụng chức năng này từ ngôn ngữ 1C tích hợp. Việc lấy tọa độ hiện tại của thiết bị có thể được chia thành 2 giai đoạn: chọn nhà cung cấp dịch vụ định vị địa lý và xử lý tọa độ nhận được:

// Hãy cung cấp lựa chọn nhà cung cấp cho nền tảng IdealProvider = Công cụ định vị địa lý.Get Most PrecisionProvider(); Tọa độ = GeoPositioningTools.GetLastLocation(IdealProvider); // Nếu tọa độ đã được nhận từ lâu, thì hãy cập nhật If Tọa độ = Không xác định HOẶC CurrentDate() – Tọa độ.Date > 3600 Then Geopositioning Tools.UpdateLocation(IdealProvider, 60); Tọa độ = GeoPositioningTools.GetLastLocation(IdealProvider); endIf;

Làm việc với các tính năng đa phương tiện

Nhà phát triển có cơ hội chụp ảnh, quay video và ghi âm bằng ngôn ngữ tích hợp: Chụp ảnh(), Thực hiện quay video(), Thực hiện ghi âm().

Hệ điều hành di động nào tốt hơn để phát triển trên 1C?

Bất chấp tình yêu của tôi dành cho công nghệ Apple, cách tốt nhất là tạo các ứng dụng di động sử dụng nền tảng 1C cho Android. Có một số lý do cho việc này, nhưng lý do quan trọng nhất là các chức năng được hỗ trợ. Thật không may, nhiều thứ cần thiết không được hỗ trợ trên iOS. Ví dụ: việc không thể đăng ký tin nhắn SMS hoặc tương tác với nhật ký cuộc gọi theo chương trình có thể khiến một số ý tưởng không thể thực hiện được. Android thân thiện hơn về mặt này. Đừng quên chi phí của chính các thiết bị. Không phải mọi công ty đều sẵn sàng chi tiền mua thiết bị di động từ Apple.

Thay vì hoàn thành

Nền tảng " 1C:Doanh nghiệp 8» đã chứng tỏ trên thực tế sự sẵn sàng trở thành một công cụ đơn giản để phát triển doanh nghiệp. Ứng dụng dành cho nền tảng di động. Các ví dụ được thảo luận trong bài viết là xác nhận bổ sung về điều này. Hoàn toàn không cần thiết phải dành nguồn lực để nghiên cứu các công cụ gốc nếu chức năng của ứng dụng phù hợp với khả năng của nền tảng di động và công ty bị thống trị bởi các sản phẩm 1C.

Bài viết này dành cho những ai quan tâm đến client di động. Chúng ta sẽ xem xét việc cài đặt ứng dụng khách di động trên Android, kết nối gỡ lỗi và tập hợp ứng dụng apk trong cấu hình “Trình tạo ứng dụng di động”.

Cuối cùng, nền tảng di động thử nghiệm 8.3.12 đã xuất hiện và bây giờ chúng ta có thể kiểm tra hoạt động của ứng dụng khách di động. Không biết bạn thế nào, nhưng nhiều nhà phát triển mà tôi biết đã chờ đợi điều này kể từ khi bài viết về “1C: Through the Looking Glass” (Ứng dụng di động) được xuất bản.

Tôi cho rằng bạn đã quen với việc cài đặt một ứng dụng di động và trình tạo ứng dụng di động, đồng thời bạn cũng đã cài đặt Android SDK, Apache Ant, v.v. Hiện đã có rất nhiều bài viết về chủ đề này.

Đối với các thử nghiệm của chúng tôi, hãy lấy cấu hình demo “Ứng dụng được quản lý” và trước tiên, hãy thử kết nối nó với ứng dụng khách di động được tạo sẵn. Trong trường hợp của tôi, bản phân phối ứng dụng khách là tệp “1cem-client-arm.apk”. Khả năng cài đặt ứng dụng từ các nguồn không xác định trước tiên phải được bật trên điện thoại thông minh của bạn. Đối với tôi nó trông như thế này:

Máy khách di động tương tự như máy khách web, do đó, để truy cập cơ sở dữ liệu, nó phải được xuất bản trên máy chủ web. Ở đây mọi thứ đều chuẩn, tôi xuất bản lên máy chủ web IIS có tên là “demo”. Cơ sở dữ liệu của tôi dựa trên tệp, vì vậy tôi cần cấp quyền đối với thư mục cho người dùng IUSR. Tôi rất vui vì chính hệ thống đã nhắc nhở tôi về điều này.

Kết nối cơ sở dữ liệu trong ứng dụng khách di động:

Tất nhiên, không thể vào cơ sở dữ liệu ngay lập tức. Vấn đề là Quản trị viên mở quá trình xử lý để làm việc với email và cố gắng đặt biểu tượng cho thanh tác vụ, biểu tượng này không có trong ứng dụng khách di động. Vì chức năng này cũng không có sẵn trong máy khách web nên mã được đóng khung trong chỉ thị biên dịch “#If Not WebClient Then”. Chúng ta chỉ cần tìm tất cả những nơi sử dụng lệnh này và thay đổi nó thành “#If Not WebClient AND Not MobileClient Then”. Đối với những người mới bắt đầu, điều này là khá đủ và cuối cùng chúng ta có thể thấy ứng dụng khách di động hoạt động. Giao diện lệnh trông như thế này:

Dưới đây là danh sách các đối tác:

Tất nhiên, đây không phải là tất cả những nơi cần được điều chỉnh cho phù hợp với ứng dụng khách di động. Bạn có thể kiểm tra cấu hình bằng cách sử dụng “Menu chính - Cấu hình - ---Kiểm tra cấu hình”:

Tôi tìm thấy 84 lỗi, bao gồm cả các đối tượng siêu dữ liệu không được hỗ trợ. Cộng với ba vị trí đó trong mã mà tôi đã giới hạn bằng các lệnh. Vì vậy, bạn vẫn phải nỗ lực thích ứng, nhưng điều này chắc chắn không giống như việc viết một ứng dụng di động từ đầu.

Việc khởi chạy dưới các vai trò khác cũng diễn ra theo cách tương tự, bạn chỉ cần đặt quyền khởi chạy ứng dụng khách di động.

Nếu chúng tôi không hiểu lỗi là gì, việc gỡ lỗi sẽ giúp chúng tôi. Nó có sẵn trong ứng dụng khách di động, nhưng chỉ sử dụng tính năng gỡ lỗi HTTP. Tôi có cơ sở dữ liệu tệp nên tôi sẽ sử dụng máy chủ gỡ lỗi cục bộ (“Công cụ - Tùy chọn - Gỡ lỗi”) và thiết lập kết nối tự động cho máy khách di động (“Gỡ lỗi - Kết nối - Kết nối tự động”):

Chỉ định các tham số và bạn đã hoàn tất:

Quá trình thiết lập cho ứng dụng khách apk được chuẩn bị trước từ 1C đã hoàn tất.

Bây giờ hãy xây dựng gói ứng dụng của chúng tôi bằng cách sử dụng trình tạo ứng dụng di động. Thành thật mà nói, lần đầu tiên tôi đã dành vài giờ để xây dựng ứng dụng. Quá trình lắp ráp vẫn tiếp tục nhưng một danh sách cơ sở dữ liệu trống đã mở ra.

Và vì vậy, chúng tôi có một kho lưu trữ phiên bản di động của nền tảng. Chúng tôi tải nó lên thư mục “Phiên bản di động”:

Trong cài đặt bộ sưu tập, một mục riêng đã xuất hiện cho SDK 26 trở lên (đối với những người, giống như tôi, đã lâu không cập nhật, hãy khởi chạy Trình quản lý SDK và tải xuống các gói mới):

Tiếp theo bạn cần chuẩn bị file cấu hình. Chính với bước này, tôi đã gặp vấn đề ngay từ đầu. Sau đó tôi mở tài liệu và mọi thứ trở nên rõ ràng hơn một chút. Hướng dẫn dành cho nhà phát triển nói như sau về điều này: "Mỗi cấu hình có thể hoạt động trong ứng dụng khách di động đều chứa một số thông tin phụ trợ cho phép bạn theo dõi việc thay thế cấu hình."
Tệp cấu hình phải được ký. Trong trường hợp này, đối với mỗi cấu hình, khóa riêng của nó được tạo và khóa chung (trường DSAKey) được tải lên tệp 1cemca.xml để so sánh chữ ký cấu hình.

Để tạo khóa và chữ ký, hãy truy cập các thuộc tính của cấu hình “Chữ ký ứng dụng khách di động” (ngay dưới các quyền bắt buộc, nếu thuộc tính của bạn được chia theo danh mục và không theo thứ tự bảng chữ cái) và xem cài đặt chữ ký:

Đầu tiên, chúng ta tạo một khóa riêng và giấu nó khỏi gián điệp và kẻ thù. Tiếp theo, chúng ta tạo chữ ký cấu hình. Trong tương lai, hướng dẫn sử dụng khuyên bạn nên chuyển tới “Menu chính - Cấu hình - Máy khách di động - Thiết lập việc sử dụng ứng dụng khách di động”. Trong hộp thoại, chọn hộp kiểm “Xác minh chữ ký ứng dụng khách di động khi cập nhật cấu hình cơ sở dữ liệu” và nhấp vào nút “OK”. Đánh giá theo hướng dẫn sử dụng, chữ ký sẽ thay đổi nếu chúng tôi thay đổi thành phần hoặc tên của các loại đối tượng siêu dữ liệu, cũng như tên và/hoặc thành phần của các khóa nhập đăng ký. Những thứ kia. việc thay đổi biểu mẫu chắc chắn không ảnh hưởng đến chữ ký và theo mô tả, việc thay đổi thành phần chi tiết của các thư mục và tài liệu hiện có (nhưng điều này không chắc chắn).

Chữ ký đã sẵn sàng, chúng ta có thể tiếp tục. Hãy để tôi nói ngay cho bạn biết rằng các quy trình nền không có sẵn trong ứng dụng khách di động, vì vậy chúng cần được tắt trong quyền của ứng dụng khách di động. Chia sẻ tập tin từ PC cũng không khả dụng. Ngoài ra, tôi đã tắt tính năng định vị địa lý để trong quá trình lắp ráp không xảy ra lỗi do thiếu phím để làm việc với bản đồ. Tôi đã kết thúc với danh sách các quyền sau:

Bằng cách nào đó một cách lặng lẽ và không có bất kỳ mô tả đặc biệt nào về công việc, 1C đã phát hành cấu hình “Trình thu thập ứng dụng di động”, nhằm mục đích trở thành một loại công cụ tổ chức để phát triển ứng dụng di động.

Trong phiên bản mới nhất 1.0.3.17 hiện tại có một số vấn đề nhỏ mà thoạt nhìn có vẻ giống như lỗi.

Vấn đề đầu tiên chúng tôi gặp phải là không thể khởi chạy cấu hình mà không có người dùng, chúng tôi gặp lỗi sau:

“Phiên bản cấu hình khác với phiên bản cơ sở thông tin. Cần phải cập nhật cấu hình bằng cách chạy giải pháp ứng dụng với tư cách là người dùng có quyền Quản trị viên.

Vấn đề này có thể được giải quyết khá đơn giản; bạn chỉ cần khởi chạy trình cấu hình và thêm người dùng có quyền “Quản trị viên”.

Sự cố thứ hai xảy ra khi chúng tôi cố gắng tạo một phần tử trong thư mục “Cấu hình di động”. Chúng tôi nhấp vào nút “Tạo” và gặp lỗi “Chỉ có thể tạo các mục trong nhóm”:

Không sao cả, chúng tôi nhấp vào nút “Tạo nhóm” và đột nhiên chúng tôi lại nhận được thông báo lỗi “Chỉ có thể tạo các mục trong nhóm”.

Giải pháp là làm như sau:

Trên bảng trên cùng có nút “Tạo” để hiển thị menu con. Trong đó nhấn vào mục “Cấu hình di động”:

Sau đó, một cửa sổ khá thân thiện sẽ mở ra, trong đó bạn có thể tạo nhóm:

Ngoài ra còn có vấn đề khi tạo mục thư mục “Ứng dụng di động”, chúng tôi nhận được thông báo lỗi sau:

"Tiền tố ID ứng dụng không được đặt trong cài đặt nhà cung cấp":

Lối ra cũng khá gần:

Và chúng tôi bắt đầu nhập dữ liệu vào phần tử thư mục “Nhà cung cấp giải pháp di động”.

Tiền tố phải có dấu chấm bên trong. Và nhấp vào “Tạo khóa nhà phát triển”.