Cách cung cấp thuộc tính Hệ thống cho bài kiểm tra của tôi qua Gradle và -D


103

Tôi có một chương trình Java đọc thuộc tính Hệ thống

System.getProperty("cassandra.ip");

và tôi có một tệp xây dựng Gradle mà tôi bắt đầu với

gradle test -Pcassandra.ip=192.168.33.13

hoặc là

gradle test -Dcassandra.ip=192.168.33.13

tuy nhiên System.getProperty sẽ luôn trả về null .

Cách duy nhất tôi tìm thấy là thêm nó vào tệp xây dựng Gradle của tôi qua

test {
    systemProperty "cassandra.ip", "192.168.33.13"
}

Làm cách nào để làm điều đó qua -D


1
Điều gì xảy ra khi bạn sử dụng gradle -Dcassandra.ip=192.168.33.13? Dù sao đi nữa, nhiệm vụ thử nghiệm sẽ phân chia một hoặc một số JVM mới. Vì vậy, bạn sẽ phải chuyển các thuộc tính một cách rõ ràng. Tuy nhiên, không ai bắt bạn phải mã hóa giá trị của chúng trong bản dựng.
JB Nizet

Cũng hãy xem câu trả lời này: stackoverflow.com/questions/23689054/…
IgalS

Câu trả lời:


123

Cờ -P dành cho các thuộc tính gradle và cờ -D dành cho các thuộc tính JVM. Bởi vì bài kiểm tra có thể được phân nhánh trong một JVM mới, đối số -D được chuyển cho gradle sẽ không được truyền sang bài kiểm tra - có vẻ như đó là hành vi bạn đang thấy.

Bạn có thể sử dụng systemProperty trong testkhối của mình như bạn đã làm nhưng dựa trên thuộc tính gradle đến bằng cách chuyển nó với nó -P:

test {
    systemProperty "cassandra.ip", project.getProperty("cassandra.ip")
}

hoặc cách khác, nếu bạn đang chuyển nó qua -D

test {
    systemProperty "cassandra.ip", System.getProperty("cassandra.ip")
}

1
Đây không phải làm việc cho tôi (thử nghiệm sử dụng System.getProperties().stringPropertyNames().forEach(System.out::println);trong mã Java, nó không xuất hiện)
CLOVIS

Cảnh báo: getPropertyném MissingPropertyExceptionnếu tài sản không được tìm thấy. Sử dụng Eron của câu trả lời thay: stackoverflow.com/a/43112126/915441
Yngvar Kristiansen

1
Thêm giá trị mặc định vào gradle.propertiessẽ ngăn chặn MissingPropertyException.
Duncan Calvert

Tôi không thể làm cho cả hai phương pháp này hoạt động. Bất cứ điều gì tôi làm, Tài sản của tôi luôn không có giá trị. Điều này cũng bao gồm tất cả các phương pháp được đề cập bên dưới. Tôi đang tự hỏi liệu đây có phải là điều gì đó để làm với phiên bản mới hơn, vì tất cả các nhận xét là từ năm 2018? @CLOVIS bạn đã tìm ra giải pháp cho vấn đề này chưa?
Hester Lyons

@HesterLyons Tôi chỉ muốn biết liệu bản dựng đang thử nghiệm hay đang chạy bình thường, vì vậy tôi đã sử dụng thuộc tính gradle tự thêm vào khi thử nghiệm; bạn có thể xem mã tại đây: github.com/CLOVIS-AI/wildfyre-java/blob/master/src/main/java/…
CLOVIS

27

Gặp phải vấn đề này rất nhiều, ngoại trừ tôi không muốn liệt kê tất cả các thuộc tính được cung cấp trên dòng lệnh trong tập lệnh gradle một lần nữa. Do đó, tôi gửi tất cả các thuộc tính hệ thống đến bài kiểm tra của mình

task integrationTest(type: Test) {
    useTestNG()
    options {
        systemProperties(System.getProperties())
    }
}

Hãy cẩn thận khi làm điều này. Nó có thể dễ dàng phá vỡ các kiểm tra cập nhật của Gradle khi các thuộc tính hệ thống thay đổi trong khi gọi.
thokuest

9

Tôi đã gặp trường hợp cần chuyển nhiều thuộc tính hệ thống vào JVM thử nghiệm nhưng không phải tất cả (không muốn chuyển những thuộc tính không liên quan). Dựa trên các câu trả lời ở trên và bằng cách sử dụng subMapđể lọc những câu tôi cần, điều này đã làm việc cho tôi:

task integrationTest(type: Test) {
    // ... Do stuff here ...
    systemProperties System.getProperties().subMap(['PROP1', 'PROP2'])
}

Trong ví dụ này, chỉ PROP1PROP2sẽ được chuyển vào, nếu chúng tồn tại trong JVM của gradle.


5

Đây là một biến thể chuyển nhiều thuộc tính dự án sang JVM thử nghiệm làm thuộc tính hệ thống. Tôi thích thuộc tính dự án hơn thuộc tính hệ thống để tăng tính linh hoạt.

task intTest(type: Test) {
    systemProperties project.properties.subMap(["foo", "bar"])
}

Có thể được chuyển trên dòng lệnh:

 $ gradle intTest -Pfoo=1 -Pbar=2

Và được truy xuất trong thử nghiệm của bạn:

String foo = System.getProperty("foo");

Khi chạy System.getProperty("someprop")bằng phương thức Bản đồ con đó, tôi đã nhận {someprop=foo}thay vì foo. Tôi đã sử dụng systemProperty "foo", project.properties.subMap(["foo"]).get("foo")trong build.gradle
Yngvar Kristiansen

@YngvarKristiansen bạn đã sử dụng ở đâu (như thế nào) systemProperty "foo"? tức là tôi đang yêu cầu xem dòng mã đầy đủ, nơi điều này đã được sử dụng? Tôi đang thử mọi thứ được đề xuất trong câu hỏi này và Gradle vẫn không chuyển bất kỳ đối số nào. Hy vọng điều này có thể giải quyết!
Hester Lyons

@HesterLyons Xin lỗi, tôi đã không giữ mã của mình nên tôi không biết nữa: \ Tôi đồng ý rằng nó có vẻ không đúng.
Yngvar Kristiansen

Cảm ơn bạn @YngvarKristiansen. Kể từ đó, tôi đã phát hiện ra rằng vấn đề của tôi là do plugin junit gradle được đưa vào gradle.build của tôi. Rất kỳ quặc.
Hester Lyons

0

Vì vậy, tôi cũng đã vấp phải vấn đề đó ngày hôm nay và những gì hiệu quả với tôi là những điều sau:

ext.env='prod'
test {
  systemProperty 'env', System.properties['env'] ?: "${env}"
  println "# test environment: " + systemProperties['env']
  ...
}

Tôi đang gọi tác vụ thử nghiệm của mình bằng -Penv = dev và tôi nhận được giá trị 'dev' trong bản in của mình, hoặc 'prod' nếu tôi không gửi bất kỳ giá trị nào, đó là hành vi mong đợi đối với tôi.

Giá trị cũng có thể truy cập ở phía java, sử dụng System.getProperty ("env") .

Kết luận của tôi về vấn đề này là giá trị đầu vào (tham số) thực sự được lưu trữ trong Hệ thống , làm cho nó có thể truy cập thông qua System.properties ['env'] hoặc System.getProperty ("env") , trong khi đầu ra (thuộc tính hệ thống) được lưu trữ trong một mảng systemProperties , làm cho nó có thể đọc được thông qua systemProperties ['env'] .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.